JavaScript Mastery

A Step-by-Step Beginner's Guide to Learning JavaScript Programming

TABLE OF CONTENTS

Introduction

Chapter 1: What is JavaScript

Chapter 2: Values, Types, and Operators

Chapter 3: Program Structure

for loops

Chapter 4: Functions

Chapter 5: Data Structures: Objects and Arrays

Chapter 6: Higher-Order Functions

Chapter 7: The Secret Life of Objects

Chapter 8: A Robot

Chapter 9: Bugs and Errors

Chapter 10: Regular Expressions

Chapter 11: Modules

Chapter 12: Asynchronous Programming

Chapter 13: Parsing

Conclusion

© ACopyright A2019 A– AChloe AAnnabler

All Arights Areserved.

The Acontent Acontained Awithin Athis Abook Amay Anot Abe Areproduced, Aduplicated, Aor Atransmitted Awithout Adirect Awritten Apermission Afrom Athe Aauthor Aor Athe Apublisher.

Under Ano Acircumstances Awill Aany Ablame Aor Alegal Aresponsibility Abe Aheld Aagainst Athe Apublisher, Aor Aauthor, Afor Aany Adamages, Areparation, Aor Amonetary Aloss Adue Ato Athe Ainformation Acontained Awithin Athis Abook, Aeither Adirectly Aor Aindirectly.

Legal ANotice:

This Abook Ais Acopyright Aprotected. AIt Ais Aonly Afor Apersonal Ause. AYou Acannot Aamend, Adistribute, Asell, Ause, Aquote Aor Aparaphrase Aany Apart, Aor Athe Acontent Awithin Athis Abook, Awithout Athe Aconsent Aof Athe Aauthor Aor Apublisher.

Disclaimer ANotice:

Please Anote Athe Ainformation Acontained Awithin Athis Adocument Ais Afor Aeducational Aand Aentertainment Apurposes Aonly. AAll Aeffort Ahas Abeen Aexecuted Ato Apresent Aaccurate, Aup Ato Adate, Areliable, Acomplete Ainformation. ANo Awarranties Aof Aany Akind Aare Adeclared Aor Aimplied. AReaders Aacknowledge Athat Athe Aauthor Ado Anot Aengage Ain Athe Arendering Aof Alegal, Afinancial, Amedical, Aor Aprofessional Aadvice. AThe Acontent Awithin Athis Abook Ahas Abeen Aderived Afrom Avarious Asources. APlease Aconsult Aa Alicensed Aprofessional Abefore Aattempting Aany Atechniques Aoutlined Ain Athis Abook.

By Areading Athis Adocument, Athe Areader Aagrees Athat Aunder Ano Acircumstances Ais Athe Aauthor Aresponsible Afor Aany Alosses, Adirect Aor Aindirect, Athat Aare Aincurred Aas Aa Aresult Aof Athe Ause Aof Athe Ainformation Acontained Awithin Athis Adocument, Aincluding, Abut Anot Alimited Ato, Aerrors, Aomissions, Aor Ainaccuracies.

A

Introduction

JavaScript Ais Aa Adistinguished Aand Adeciphered Aprogramming Alanguage Athat Aadheres Ato Athe AECMAScript Aspecification. AThe Aprogramming Alanguage Aconsists Aof Ahigh-powered Atyping, Athe Acurly Abracket Asyntax, Atop-quality Afunctions, Aand Aprototype-based Aobject-orientation. AAccompanied Aby AHTML Aand ACSS, AJavaScript Ais Aone Aof Athe Asignificant Atechnologies Aof Athe AWorld AWide AWeb. AJavaScript Afacilitates Ainterchangeable Aweb Apages Aand Ais Aa Avital Apart Aof Aweb Aapplications. AAlmost Aevery Awebsite Autilizes AJavaScript, Aand Aall Athe Asignificant Aweb Abrowsers Aconsist Aof Athe AJavaScript Aengine Ato Afunction Acorrectly. ABrendan AEich Adeveloped AJavaScript Ain A1995 Awhen Ahe Awas Awith ANetscape ACommunications. AJavaScript Aaids Afunctional, Aevent-driven, Aprototype-based Aand Aobject-oriented Aprogramming Astyles. AJavaScript Aupgrades Aweb Auser Ainterface Aby Aaffirming Aactivities Ataken Aon Athe Aclient-side Aby Athe Auser. AYou Acan Ainsert AJavaScript Aengines Ainto Adifferent Atypes Aof Ahost Asoftware, Awhich Aincludes Adatabases Aand Aweb Aservers, Aand Anon-web Arelated Aprograms Alike Aword Aprocessors.

The Aconcepts Aof AJavaScript Aare Aexplained Afurther Ain Athis Abook Awith Athe Agoal Ato Ahelp Ayou Alearn Aand Aunderstand AJavaScript Alanguage Awithout Apressure. AThe Aknowledge Aof AHTML, Atext Aeditor, Aweb Abrowser, Aand ACSS Aare Aall Athat's Aneeded Ato Alearn AJavaScript. ATo Aget Athe Alearning Aprocess Astarted, Aone Aof Athe Aessential Atools Ais Aa Atext Aeditor, Aand Ait Ais Arequired Ato Awrite Acodes. AYou’ll Aalso Aneed Aa Abrowser Ato Aunveil Ayour Adeveloped Aweb Apages. AThere Aare Adifferent Atypes Aof Atext Aeditors Asuch Aas Athe ASublime AText, ANotepad++ Aand Abrowsers Asuch Aas AFirefox, AGoogle AChrome, Aand Aso Aon. A

A

Chapter 1: What is JavaScript

JavaScript, Aabbreviated AJS, Ais Aa Ahigh-level Aprogramming Alanguage Aintroduced Ato Aadd Aspecific Aprograms Ato Aweb Apages, Aand Ait Ahas Abeen Aadopted Aby Aall Amajor Aweb Abrowsers. AJavaScript Acan Abe Aused Ato Abuild Ainteractive Aweb Aapplications Ato Afunction Aappropriately Awithout Areloading Aevery Apage Aper-action. AJavaScript Ais Aused Ato Acreate Adifferent Aforms Aof Aactivities Awithin Aweb Apages Aand Ais Aone Aof Athe Aessential Acomponents Aof Athe AWorld AWide AWeb A(www), Awhich Aare AHTML A(Hypertext AMarkup ALanguage) Aand ACSS A(Cascading AStyle ASheets). AJavaScript Aand AHTML Aare Aused Ato Adevelop Aweb Apages. AJavaScript Abrings Aa Apage Ato Alife Aby Aadding Aspecial Aeffects Asuch Aas Asliders, Apop-ups, Aform Avalidations, Aetc. ACSS Adetermines Athe Acolor Aintensity, Aimage Asize, Abackground Acolors, Atypeface, Afont Asize, Aetc.

Client-Side AJavaScript

Client-Side AJavaScript Ais Athe Ausual Aform Aof AJavaScript Alanguage. AThe Ascript Amust Abe Ainserted Aor Areferenced Aby Aan AHTML Adocument Aso Athat Athe Abrowser Acan Ainterpret Athe Acode. AIt Aenables Aweb Apages Ato Ainclude Ainteractive Aprograms Awith Athe Auser, Adevelop AHTML Acontent Adynamically, Aand Acommand Athe Abrowser. AUsers Ause AJavaScript Acode Awhen Athey Awant Ato Asubmit Aforms Aand Aalso Adetermine Aif Aall Aentries Aare Avalid Abefore Ait Atransfers Athem Ato Athe Aserver.

Advantages Aof AJavaScript

· AWith AJavaScript, Ausers Acan Aorganize Ainput Abefore Agetting Athe Apage Asent Ato Athe Aserver, Awhich Aautomatically Areduces Aloads Aon Athe Aserver.

· AJavaScript Aenables Aswift Aresponse Ato Apage Avisitors. AThe Apage Adoes Anot Ahave Ato Areload Abefore Avisitors Acan Asee Aif Athere Awas Aan Aerror Ain Atyping.

· AJavaScript Ais Aused Ato Abuild Aa Areactive Ainterface Athat Agives Aa Areaction Awhen Athe Amouse Ahovers Aover Athem.

Limitations Aof AJavaScript

JavaScript Aprogramming Alanguage Alacks Athe Afollowing Aessential Afeatures. AThey Aare:

· AFor Asecurity Areasons, Aclient-side AJavaScript Adoes Anot Aread Aor Awrite Afiles

· AJavaScript Afor Anetworking Aapplications

· AJavaScript Adoes Anot Acontain Amultiprocessor Acapabilities

JavaScript ADevelopment ATools

You Ado Anot Aneed Aan Aexpensive Adevelopment Atool Ato Awrite AJavaScript Acodes. AYou Acan Awrite Awith Aa Asimple Atext Aeditor Asuch Aas AMicrosoft AFrontPage, AMacromedia ADreamweaver AMX, AMacromedia AHomeSite A5, Aetc.

Javascript APlacement

JavaScript Acode Ais Ainserted Aanywhere Ain Aan AHTML Adocument. AHowever, Ayou Awant Ato Ainsert AJavaScript Acode Ain Aan AHTML Afile Alike Athis:

The AScript Awithin A<head> A</head> Apart.

The AScript Awithin A<body> A</body> Apart.

The AScript Awithin A<body> A</body> Aand A<head> A</head> Apart.

Include Aexternal Afile AScript Ain Athe A<head>...</head> Apart.

JavaScript Ain A<head>...</head> ASection

In Asome Acases, Awhen Ayou Awant Athe Ascript Ato Arun Aon Aa Aspecial Aevent, Asuch Aas Aan Aaction Awhen Aa Abutton Aclicked, Aplace Athe Ascript Ain Athe Ahead Asection Alike Athis:

<html>

<head>

<script Atype="text/JavaScript">

<!--

function AsayHi() A{

alert("Hello AWorld")

}

//-->

</script>

</head>

<body>

Tap Ahere Afor Aresult

<input Atype="button" Aonclick="sayHi()" Avalue="Say AHi" A/>

</body>

</html>

JavaScript Ain A<body>...</body> ASection

Sometimes Ayou Awant Aa Ascript Ato Arun Aimmediately Aand Ato Acreate Ascript Aon Athe Acontent Apage, Ainsert Athe Ascript Awithin Athe A<body> Asection. AThis Ais Awhat Athe Acode Ashould Alook Alike:

<html>

<head>

</head>

<body>

<script Atype="text/JavaScript">

<!--

document.write("Hello AWorld")

//-->

</script>

<p>This Ais Aweb Apage Abody A</p>

</body>

</html>

JavaScript Ain A<body> Aand A<head> ASections

Insert Ayour AJavaScript Acode Ain A<head> Aand A<body> Asection Alike Athis:

<html>

<head>

<script Atype="text/JavaScript">

<!--

function AsayHi() A{

alert("Hello AWorld")

}

//-->

</script>

</head>

<body>

<script Atype="text/JavaScript">

<!--

document.write("Hello AWorld")

//-->

</script>

<input Atype="button" Aonclick="sayHi()" Avalue="Say AHi" A/>

</body>

</html>

JavaScript Ain AExternal AFiles

To Aavoid Athe Ause Aof Aidentical AJavaScript Acode Arepetition, Athe Alanguage Aenables Ayou Ato Acreate Aan Aexternal Afile Aand Astore AJavaScript Acodes Aand Athen Aintegrate Athe Aexternal Afile Ainto Athe AHTML Afiles. AThe Asample Abelow Adisplays Ahow Ato Aintegrate Aan Aexternal AJavaScript Afile Awithin Athe AHTML Acode Autilizing Athe Ascript Atag Aand Asrc Aattribute.

<html>

<head>

<script Atype="text/javascript" Asrc="filename.js" A></script>

</head>

<body>

.......

</body>

</html>

The Aexternal Afile Asource Afile Ashould Abe Asaved Awith Aan Aextension A.js.

Summary

In Athis Afirst Achapter, Awe Aexplained Athe Aorigination Aof AJavaScript Aand Aits Aplacement Ainto Ainternal Aand Aexternal Afiles. AWe Adiscussed Athe Ause Aof AJavaScript Ato Abuild Ainteractive Aweb Aapplications Ato Aperform Aappropriately Awithout Ahaving Ato Areload Aevery Apage Aper-action.

Exercise

How Ado Ayou Ainsert AJavaScript Acode Ainto Athe Ahead, Abody Aand Ainclude Aexternal Afile Ascript Ain Aan AHTML Adocument?

Solution

The AScript Afor Athe Ahead Apart Ais A<head> A</head>.

The AScript Afor Athe Abody Apart Ais A<body> A</body>.

The AScript Awithin Athe Abody Ais A<body> A</body> Aand A<head> A</head>.

The AScript Ato AInclude Aexternal Afile AScript Ain Athe A<head>...</head>.

Chapter 2: Values, Types, and Operators

In Athe Aworld Aof Acomputers, Athere Ais Adata. AYou Acan Acreate Anew Adata, Aread Adata Aand Achange Adata, Awhich Aare Aall Astored Aas Aa Alook-alike Along Asuccession Aof Abits. ADefine Abits Aas Azeros Aand Aones Athat Atake Aa Astrong Aor Aweak Asignal, Aand Ahigh Aor Alow Aelectrical Acharge Afrom Ainside Athe Acomputer. AAll Adata Aand Apieces Aof Ainformation Aare Adescribed Aas Aa Asuccession Aof Azeros Aand Aones Aand Arepresented Ain Abits.

Values

Take Aa Adeep Abreath Aand Athink Aof Aan Aocean Aof Abits. AThe Alatest APCs Acontains Amore Athan A30 Abillion Abits Ain Aits Adata Astorage. AWe Ause Abits Ato Acreate Avalues. AThe Acomputer Acan Afunction Acorrectly Abecause Aevery Abit Aof Ainformation Ais Asplit Ainto Avalues. AEvery Avalue Aconsists Aof Aa Atype Athat Ainfluences Aits Arole, Aand Avalues Acan Abe Anumbers, Atext Aor Afunctions, Aetc. ATo Agenerate Avalue, Ayou Aneed Ato Ainvoke Aits Aname, Aand Ait Aappears Afrom Awhere Ait Awas Astored.

Arithmetic

Arithmetic Ais Athe Amajor Athing Ato Ado Awith Anumbers. AThe Amultiplication, Aaddition, Aand Asubtraction Aof Amore Athan Aone Anumber Ato Aproduce Aanother Anumber Ais Aan Aarithmetic Aoperation. AThis Ais Aan Aexample Aof Awhat Athey Alook Alike Ain AJavaScript:

100 A+ A4 A* A11

The A+ Aand A* Asymbols Aare Acalled Aoperators, Athe Afirst Ameans Aaddition Awhile Athe Aother Ameans Amultiplication. AAn Aoperator Ainserted Abetween Atwo Avalues Awill Aproduce Aanother Avalue. AThe A- Aoperator Ais Afor Asubtraction Aand Athe A/ Aoperator Ais Afor Athe Adivision. AIf Aoperators Ashow Atogether Awithout Aparentheses, Athe Aprecedence Aof Athe Aoperators Adecides Athe Away Athey Aare Aapplied. AIf Aseveral Aoperators Awith Athe Asame Aprecedence Ashow Aright Anext Ato Aeach Aother Alike A1 A- A2 A+ A1, Aapply Athem Aleft Ato Aright: A(1 A- A2) A+ A1.

Special Anumbers

JavaScript Aconsists Aof Athree Aunique Avalues Athat Ado Anot Aact Alike Anumbers Abut Aare Aregarded Aas Anumbers. AInfinity Aand A-Infinity Aare Athe Afirst Atwo, Awhich Amean Athe Apositive Aand Anegative Ainfinities, Aand Athe Alast Avalue Ais Athe ANaN. ANaN Asays A“not Aa Anumber,” Aalthough Ait Ais Aa Avalue Aof Athe Anumber Atype.

Strings

A Astring Ais Athe Asuccession Aof Anumbers. AThe Astring Ais Athe Anext Adata Atype, Aand Athey Arepresent Atext. AStrings Aconfine Atheir Acontent Ain Aquotes.

`Down Athe Awalkway Apath. A`

"On Atop Aof Athe Aroof."

'I Aam Aat Ahome.'

Quotes Aare Aused Ain Adifferent Atypes Alike Athe Adouble Aquotes, Asingle Aquotes, Aor Athe Abackticks Ato Amark Astrings. AIt Ais Aessential Athat Athe Astrings Amatch. AThe Aelements Awithin Athe Aquotes Acreate Aa Astring Avalue Aby AJavaScript. AJavaScript Auses Athe AUnicode Astandard Ato Aassign Aa Anumber Ato Aevery Acharacter Aneeded, Aincluding AArabic, AArmenian, AJapanese, Aetc. AYou Acannot Asubtract, Amultiply, Aor Adivide Astrings Abut Ayou Acan Ause Athe A+ Aoperator, Awhich Awill Anot Aadd Abut Aconcatenates Atwo Astrings Atogether. AConcatenation Ameans Ato Aglue Astrings Atogether.

Unary Aoperators

Symbols Ado Anot Arepresent Aall Athe Aoperators. AYou Acan Awrite Asome Aoperators Ain Awords. AA Aclear Aexample Ais Aa Atype Aof Aoperator, Aand Athis Aoperator Acreates Aa Astring Avalue Awith Athe Aname Aof Athe Atypeof Aits Aattached Avalue.

console.log(typeof A4.5)

// A→ Anumber

console.log(typeof A"x")

// A→ Astring

The Asecond Adisplayed Aoperator Ais Acalled Athe Abinary Aoperator Abecause Athey Ause Atwo Avalues, Awhile Aoperators Athat Ause Aone Avalue Aare Athe Aunary Aoperator.

console.log(- A(10 A- A2))

// A→ A-8

Boolean Avalues

Boolean Ais Aa Avalue Athat Adiffers Aonly Abetween Atwo Apossibilities Asuch Aas A“on” Aand A“off” Aand Aso Aon. AThe ABoolean Aconsists Aof Aonly Atrue Aand Afalse.

Comparison

Comparison Ais Aa Away Ato Acreate ABoolean Avalues:

console.log(3 A> A2)

// A→ Atrue

console.log(3 A< A2)

// A→ Afalse

The A> Aand A< Acharacters Aare Athe Asigns Athat Arepresent A“is Agreater Athan” Aand A“is Aless Athan,” Aaccordingly. AYou Acan Ause Abinary Aoperators Ain Aa ABoolean Avalue Athat Adetermines Aif Athe Acontained Avalue Aif Atrue Aor Afalse.

You Acan Acompare Astrings Ain Athe Asame Amanner.

console.log("Aardvark" A< A"Zoroaster")

// A→ Atrue

You Acan Ainstruct Astrings Ain Aalphabetical Aorder, Auppercase Aletters Aare Aoften A“less” Athan Alowercase, Aso A"Z" A< A"a," Aand Anon-alphabetic Acharacters A(! A-, Aand Aso Aon) Aare Aalso Apresent Ain Athe Aordering. AWhen AJavaScript Awant Ato Acompare Astrings, Ait Arecognizes Acharacters Afrom Aleft Ato Aright, Adifferentiating Athe AUnicode Acodes Aindividually.

Here Aare Aother Arelated Aoperators A<= A(less Athan Aor Aequal Ato), A>= A(greater Athan Aor Aequal Ato), A== A(equal Ato), Aand!= A(not Aequal Ato).

console.log("Itchy" A!= A"Scratchy")

// A→ Atrue

console.log("Apple" A== A"Orange")

// A→ Afalse

In AJavaScript, Athere Ais Aonly Aone Avalue Athat Ais Anot Aequal Ato Aitself, Awhich Ais Athe ANaN A(“not Aa Anumber”).

console.log(NaN A== ANaN)

// A→ Afalse

Logical Aoperator

JavaScript Aendorses Aonly Athree Aoperators Athat Ayou Acan Aapply Ato ABoolean Avalues, Athey Aare Aand, Aor, Aand Anot. AThe A&& Aoperator Asignifies Alogical Aor Aand Aits Aresults Adepend Aon Awhere Athe Avalues Aimputed Aare Atrue Aor Afalse.

console.log(true A&& Afalse)

// A→ Afalse

console.log(true A&& Atrue)

// A→ Atrue

The A|| Aoperator Aindicates Alogical Aor. AThis Aoperator Aoutputs Atrue Aif Athe Agiven Avalue Ais Atrue.

console.log(false A|| Atrue)

// A→ Atrue

console.log(false A|| Afalse)

// A→ Afalse

An Aexclamation Amark A(!) Aindicates ANot. AIt Ais Aan Aoperator Athat Aoverturns Athe Aset Avalue, Aand Ait Achanges Afrom Atrue Ato Afalse Aand Afalse Ato Atrue.

The A|| Aconsists Aof Athe Alowest Aprecedence Aof Aall Aoperators, Athen A&&, Athe Acomparison Aoperators A(>, A==, Aetc.), Aand Aso Aon. AThe Aexample Abelow Astates Athat Aparentheses Aare Anecessary:

1 A+ A1 A== A2 A&& A10 A* A10 A> A50

Empty Avalues

Null Aand Aundefined Aare Athe Aonly Atwo Atypes Aof Aspecial Avalues Athat Aare Aused Ato Aindicate Athe Anon-appearance Aof Aan Aimportant Avalue. AThey Acontain Azero Adata.

Automatic Atype Aconversion

Earlier AI Asaid Athat AJavaScript Aaccepts Apractically Aall Agiven Aprograms, Aincluding Aprograms Awith Aodd Abehaviors. AAutomatic Atype Aconversion Aillustrates Ain Athe Afollowing Aexpressions:

console.log(8 A* Anull)

// A→ A0

console.log("5" A- A1)

// A→ A4

console.log("5" A+ A1)

// A→ A51

console.log("five" A* A2)

// A→ ANaN

console.log(false A== A0)

// A→ Atrue

When Ayou Aassign Aan Aoperator Athe Awrong Avalue, AJavaScript Asilently Areturns Athat Avalue Ato Athe Aexact Atype Ait Arequires Ausing Athe Atype Acoercion Arule. AIn Athe Afirst Aexpression, Athe Anull Aturns Ato A0, Aand Athe A5 Ain Athe Asecond Aremains A5 A(from Astring Ato Anumber). AIn Athe Athird Aexpression, Athere Awas Aa Astring Aconcatenation Abefore Athe Anumeric Aaddition, Awhich Aconverts Athe A1 Ato A1 A(from Anumber Ato Aa Astring). AWhen Aodd Anumbers Asuch Aas A"five" Aor Aundefined Achanges Ato Athe Anumber, Ait Agets Athe Avalue Aof ANaN. AIf Ayou Awant Ato Adifferentiate Abetween Avalues Aof Athe Asame Atype Ausing A==, Athe Aoutput Ashould Abe Atrue Aif Athe Avalues Aare Asimilar Aexcept ANaN. AIf Ayou Awant Ato Atest Aif Aa Avalue Acontains Aa Areal Avalue, Ause Athe A== A(or! A=) Aoperator Ato Acompare Ait. ATo Aavert Aunexpected Atype Aconversions, Ause Athe Athree-character Acomparison Aoperators.

Short-circuiting Aof Alogical Aoperators

The A&& Aand A|| Aare Acalled Athe Alogical Aoperators. AThey Aare Aused Ato Ahold Aseveral Atypes Aof Avalues Ain Aa Aspecific Away. AThey Achange Athe Avalues Acontained Ain Athe Aleft Aside Ato ABoolean Atype Ato Adecide, Aalthough Ait Adepends Aon Athe Aoperators Aand Athe Atype Aof Agenerated Aresult, Abut Awill Aalways Areinstate Athe Aleft Aor Aright-hand Avalue. AThe A|| Aoperator Asends Aback Avalue Ato Athe Aleft Awhen Ait Acan Abe Achanged Ato Atrue Aand Awill Areinstate Athe Avalue Ato Athe Aright.

console.log(null A|| A"user")

// A→ Auser

console.log("Kate" A|| A"user")

// A→ AKate

This Afunction Ais Aused Ato Areturn Avalues Ato Aits Adefault Avalue Aand Aplaced Awithin Aan Aempty Avalue Aas Aa Areplacement. AStrings Aand Anumbers Ato ABoolean Avalue Aconversion Arules Aindicate Athat A0, ANaN, Aand Aempty Astring A(") Acount Aas Afalse Awhile Aother Avalues Aare Atrue. ATherefore A0 A|| A-1 Aoutputs A-1, Aand A"" A|| A"!?" Ayields A"!?". AThe A&& Aoperator Aoperates Aidentically Abut Athe Aother Away Aaround. AWhen Avalues Ato Athe Aleft Acan Abe Achanged Ato Afalse, Areturn Athe Avalue, Aor Ait Asends Athe Avalue Ato Athe Aright. ABoth Aoperators Aevaluate Athe Avalue Ato Athe Aright Aonly Awhen Ait Ais Arequired. AFor Aexample, Awe Ahave Athe Afollowing Avalues Aset Aas Atrue A|| AX, Athe Avalue Aof AX Awill Abe Atrue Aand Awill Anot Aconsider Ait. AThe Asame Arule Aapplies Ato Athe Afalse A&& AX, Awhich Athe Ax Ais Afalse Aand Awill Aoverlook Ait. AYou Acan Acall Athis Aprocess Athe Ashort-circuit Aevaluation.

Summary

This Achapter Alooks Aat Athe Afour Atypes Aof AJavaScript Avalues, Awhich Aare Astrings, Anumbers, Aundefined Avalues Aand ABooleans. AThese Avalues Aare Adeveloped Aby Ainserting Atheir Anames Aas Atrue, Anull Aor Avalue A(13, A"ABC"). AOperators Acan Aintegrate Aand Achange Avalues. AWe Alooked Aat Abinary Aoperators Afor Aarithmetic A(+, A-, A*, A/, Aand A%), Astring Aconcatenation A(+), Acomparison A(==, A!=, A===, A!==, A<, A>, A<=, A>=), Aand Alogic A(&&, A||), Aand Aalso Avarious Aunary Aoperators A(- Ato Anullify Aa Anumber, A! Ato Anullify Alogically, Aand Atype Aof Ato Asearch Afor Aa Avalue’s Atype) Aand Aa Aternary Aoperator A(?:) Ato Achoose Aone Aof Atwo Avalues Adepending Aon Aa Athird Avalue. AYou Awill Aget Asufficient Ainformation Ato Ause AJavaScript Alike Aa Asmall Acalculator, Aand Ayou Awill Aimprove Ain Athe Afollowing Achapters.

Exercise

Write Aa AJavaScript Apractice Ato Abuild Aa Avariable Athrough A
a Auser-defined Aname.

Solution

Chapter 3: Program Structure

We Awill Abegin Athe Aexpansion Aof Athe AJavaScript Aprogramming Alanguage Acommands Abeyond Asentence Afragments Aand Anouns.

Expressions Aand Astatements

A Ablock Aof Acode Athat Amanufactures Aa Avalue Ais Acalled Aan Aexpression. AA Asingle Avalue Ais Awritten Aprecisely Aas A22, Aor Apsychoanalysis Ais Acalled Aan Aexpression. AAn Aexpression Awithin Aa Abinary Aoperator Aset Ato Atwo Aexpressions Aor Awithin Aparentheses Ais Aan Aexpression. AAn Aexpression Athat Acan Aaccommodate Aother Aexpressions Acomparably Ato Ahow Athe Ahuman Alanguage Atranslates. AIt Aenables Aus Ato Adevelop Aexpressions Athat Anarrate Athe Aarbitrarily Acomplex Acomputations. AWhen Aan Aexpression Ais Acomparable Ato Aa Asentence Afragment, Athe AJavaScript Astatement Awill Acomplete Athe Asentence. AA Alist Aof Astatements Ais Acalled Aa Aprogram, Aand Athe Amost Aaccessible Atype Aof Astatement Ais Aa Aline Aof Acode Awith Aa Asemicolon Aending Ait.

For Ainstance:

1;

!false;

With Athis Afunction, Aa Astatement Acan Astand Aindependently, Aand Ait Acan Aadd Aa Afeature Athat Achanges Acolors Aoccasionally Ato Aa Ascreen Aor Amodify Athe Ainner Astate Aof Athe Amachine Ainfluencing Athe Afollowing Astatements Aafter Ait.

Bindings

JavaScript Auses Abinding Aof Avariables Ato Ahold Avalues, Afor Ainstance:

Get Amoney A= A5 A* A5;

Get Ais Athe Akeyword Ain Athat Astatement, Aand Ait Ameans Athat Athe Asentence Awill Aspecify Aa Abinding Atogether Awith Athe Abinding Aname Aand Avalue Acan Abe Aattached Ausing Athe A= Aoperator Aand Aan Aexpression. AUse Aa Adefined Abinding Aas Aan Aexpression, Aan Aexpression Acontaining Athe Abinding Avalue. AHere Ais Aan Aexample Abelow:

let Aten A= A10;

console.log(ten A* Aten);

// A→ A100

The A= Aoperator Ais Aused Aon Aexisting Abindings Ato Aremove Athe Abinding Afrom Aa Aset Avalue Aand Apoint Athem Ato Aa Anew Aone.

let Amood A= A"light";

console.log(mood);

// A→ Alight

mood A= A"dark";

console.log(mood);

// A→ Adark

Defining Aa Abinding Awithout Aassigning Aa Avalue Awill Aresult Ain Anothing Ato Ahold. ATherefore, Aasking Afor Athe Avalue Aof Aa Abinding Aproduce Athe Aundefined Avalue. AYou Acan Adefine Amultiple Abinding Aby Aa Asingle Astatement Adivided Aby Acommas.

let Aone A= A1, Atwo A= A2;

console.log(one A+ Atwo);

// A→ A3

Use Athe Avar Aand Aconst Awords Ato Adevelop Abindings Afamiliarly:

var Aname A= A"Ayad";

const Agreeting A= A"Hello A";

console.log(greeting A+ Aname);

// A→ AHello AAyad

The Aword Aconst Ameans Aconstant. AIt Adescribes Aa Aresolute Abinding, Awhich Apoints Ato Aits Aset Avalue Afor Aits Alifetime. AThese Awords Aare Aoften Aused Ato Adeclare Aa Aname Ato Aa Avalue Ato Aenable Aeasy Areference Alater Aon.

Binding Anames

Although Athere Aare Asome Areserved Awords Alike Aconst, Aclass, Adefault, Abreak, Acontinue, Adelete, Ado, Aelse Ayet Aany Aword Acan Abe Acalled Aa Abinding Aname, Ait Acan Aalso Aconsist Aof Adigits Abut Ado Anot Abegin Athe Astatement Awith Aa Afigure. AA Abinding Aname Acan Aalso Acontain Adollar Asigns A($) Aor Aunderscores A(_) Abut Ado Anot Aentertain Aany Aother Aspecial Acharacters Aor Apunctuation.

The Aenvironment

The Agroup Aof Abinding Aand Avalues Aexisting Aat Aa Astipulated Atime Ais Aknown Aas Athe Aenvironment. AWhen Ayou Alaunch Aa Aprogram, Athe Aenvironment Aholds Athe Alanguage Astandard Abinding Aand Aoften Acontains Athe Abinding Athat Acreates Ainteraction Awith Asystem Asurroundings. AFor Ainstance, Aa Abrowser Acarries Afunctions Athat Acommunicate Awith Athe Alaunched Awebsite Aas Awell Aas Aread Athe Akeyboard Aand Amouse Ainput.

Functions

A Abit Aof Aprogram Aenclosed Ain Avalue Ais Acalled Aa Afunction, Aand Athese Avalues Aare Aadded Ato Alaunch Athe Awrapped Aprogram. AFor Ainstance, Aa Afunction Athat Adisplays Aa Asmall Adialog Abox Afor Auser Ainput.

Prompt A("Enter Apasscode");

The Aprocess Aof Aeffecting Aa Afunction Ais Adescribed Aas Aa Acalling, Ainvoking, Aor Aapplying. ACall Aa Afunction Aby Ainserting Aparentheses Afollowing Aan Aexpression Athat Aprovides Aa Afunction Avalue. ASet Athe Aparenthesis Avalue Ato Athe Aprogram Awithin Athe Afunction. ADefine Avalues Aset Ato Afunctions Aas Aarguments.

The Aconsole.log Afunction

In Athe Aabove Asamples, Awe Aused Athe Aconsole.log Ato Aoutput Avalues. AAll Amajor Abrowsers Autilize Athe Aconsole.log Afunction Ato Astate Aout Aits Aarguments Ato Athe Adevice Athat Aoutputs Athe Atext. AIn Amodern Abrowsers, Athe Aoutput Ais Aoften Ain Athe AJavaScript Aconsole Athat Ais Ainvisible Aby Adefault; Ayou Acan Atap Athe AF12 Acommand Aon Ayour Akeyboard Aor Athe Acommand-option-I Aon AMac. ABinding Anames Ado Anot Aaccommodate Aperiod Acharacters, Abut Aconsole.log Adoes Abecause Ait Ais Aan Aexpression Athat Areclaims Athe Alog Aproperty Afrom Athe Aconsole Abinding Avalue.

Return Avalues

Functions Aare Aused Ato Aproduce Aside Aeffects. AThey Acan Aalso Aprovide Avalues Athat Ado Anot Aneed Aside Aeffects. AFor Ainstance, Athe Afunction ACalculate.max Awill Atake Aa Asum Aof Anumber Aarguments Aand Areturns Athe Agreatest.

console.log(Calculate.max(2, A4));

// A→ A4

JavaScript Aregards Aanything Athat Aprovides Avalue Aas Aan Aexpression, Awhich Aenables Afunction Acalls Ato Aattach Ainto Athe Asubstantial Aexpression. ALet’s Acall Athe ACalculate.min, Awhich Ais Aa Adirect Aopposite Ato ACalculate.max:

console.log(Math.min(2, A4) A+ A100);

// A→ A102

Control Aflow

When Amore Athan Aone Astatement Ais Awithin Aa Aprogram, Athey Aexecute Ain Aa Astory Aform Afrom Athe Abeginning Aof Athe Acode Ato Athe Aend. AThis Atype Aof Aprogram Aconsists Aof Atwo Atypes Aof Astatement; Athe Afirst Ademand Anumbers Afrom Athe Auser Awhile Athe Asecond Adisplays Athe Asquare Aof Athe Anumber Aand Aexecutes Aimmediately Aafter Athe Afirst.

let AtheNumber A= ANumber(prompt("Select Aa Adigit A"));

console.log("Your Adigit Ais Athe Asquare Aroot Aof A" A+ AtheNumber A* AtheNumber);

A Avalue Ais Achanged Ato Aa Anumber Aby Athe Afunction Anumber Aand Aoutputs Aa Astring Avalue.

Conditional Aexecution

The Akeyboard Ais Aused Ato Adevelop Aconditional Aexecutions Ain AJavaScript. AYou Amay Awant Asome Acode Ato Aexecute Aif, Aand Aonly Aif, Aa Aspecific Acondition Ais Apositive. ALet Aus Adisplay Athe Asquare Aof Athe Ainput Aif Aonly Ait Ais Aa Anumber.

let AtheNumber A= ANumber(prompt("Select Aa Adigit A"));

if A(! ANumber.isNaN(theNumber)) A{

console.log("Your Adigit Ais Athe Asquare Aroot Aof A" A+

theNumber A* AtheNumber);

}

The Aif Akeyword Aperforms Aor Aevades Aa Astatement Adetermined Aby Athe ABoolean Aexpression Avalue. AType Athe Adetermining Aexpression Aafter Athe Akeyboard Awithin Athe Aparentheses Aaccompanied Aby Athe Astatement Ato Aaccomplish.

The ANumber.isNaN Afunction Ais Aa Ahigh-level AJavaScript Afunction Athat Aoutputs Aonly Atrue Aif Athe Astatement Ais Adeclared Aas ANaN. AThe Anumber Afunction Areturns ANaN Awhen Aan Aassigned Astring Ais Anot Aa Avalid Anumber. AStatements Aafter Athe Aif Astatement Ais Aenclosed Ain Abraces A({and}). ABraces Aare Aused Ato Acategorize Adifferent Anumbers Aof Astatement Awithin Aan Aindividual Astatement.

28

if A(1 A+ A1 A== A2) Aconsole.log("It's Atrue");

// A→ AIt's Atrue

The Aelse Akeyword Acan Abe Autilized Atogether Awith Athe Aif Astatement Ato Aprovide Atwo Adifferent Aexecution Apaths.

let AtheNumber A= ANumber A(prompt("Select Aa Adigit"));

if A(! ANumber.isNaN(theNumber)) A{

console.log("Your Adigit Ais Athe Asquare Aroot Aof A" A+

theNumber A* AtheNumber);

} Aelse A{

console.log("Hey. AWhy Adidn't Ayou Agive Ame Aa Anumber?");

}

If Athere Aare Amore Athan Atwo Apaths Ato Achoose Afrom, Ayou Acan A“chain” Amultiple

if/else Apairs Atogether. ABelow Ais Aan Aexample:

let Anum A= ANumber A(prompt("Pick Aa Anumber"));

if A(num A< A10) A{

console.log("Small");

} Aelse Aif A(num A< A100) A{

console.log("Medium");

} Aelse A{

console.log("Large");

}

The Aprogram Aconfirms Aif Athe Anum Ais Aless Athan A10, Aand Aif Ait Ais, Ait Aselects Athat Abranch, Aand Athen Adisplays A"Small". ABut Aif Athe Anum Ais Agreater Athan A10, Ait Aselects Athe Aelse Abranch Awhich Aconsists Aof Aa Asecond Aif Astatement Aof Aits Aown.

while Aand Ado Aloops

This Ais Athe Away Ato Awrite Aa Aprogram Athat Adisplays Aall Athe Aeven Anumbers Afrom A0 Ato A12.

console.log(0);

console.log(2);

console.log(4);

console.log(6);

console.log(8);

console.log(10);

console.log(12);

A Away Ato Arun Aa Aclock Aof Acode Amultiple Atimes Ais Adescribed Aas Aa Aloop.

The Alooping Acontrol Aflow Aenables Athe Auser Ato Areturn Ato Acertain Apoints Ain Awritten Aprograms Aand Aredo Ait Awith Athe Acurrent Astate Aof Athe Aprogram. AIntegrate Athis Awith Aa Abinding Athat Aenumerates Aas Afollows:

let Anumber A= A0;

while A(number A<= A12) A{

console.log(number);

number A= Anumber A+ A2;

}

// A→ A0

// A→ A2

// A… Aetcetera

A Astatement Athat Abegins Awith Athe Akeyword Aand Aat Athe Asame Atime Aproducing Aa Aloop. AThe Akeyword Awhile Aaccompanied Aby Aan Aexpression Ain Aparentheses Afollowed Aby Aa Astatement Alike Athe Aif Astatement. AThe Aloop Abecomes Acontinuous Auntil Athe Aexpression Aprovides Aa Avalue Athat Astates Atrue Awhen Atranslated Ato ABoolean. AEach Atime Athe Aloop Arepeats, Anumbers Aadopt Aa Anumber Atwice Aof Atheir Aprevious Avalue. ALet Aus Awrite Aa Aprogram Athat Aevaluates Aand Adisplay Athe Avalue Aof A210 A(2 Araised Ato Athe Apower Aof A10th). AWe Awill Autilize Atwo Abindings. AOne Ato Akeep Aan Aeye Aon Aour Aresult Aand Athe Aother Ato Acalculate Ahow Amany Atimes Athe Avalue Aof Atwo Amultiplied Aby Athe Aresult. AIt Amultiplies Auntil Athe Asecond Abinding Areaches A10:

let Aresult A= A1;

let Acounter A= A0;

while A(counter A< A10) A{

result A= Aresult A* A2;

counter A= Acounter A+ A1;

}

console.log(result);

// A→ A1024

A Ado Aloop Ais Aa Acommand Astructure Arelated Ato Aa Awhile Aloop. AA Ado Aloop Aalways Atake Aplace Aat Aleast Aonce Ain Aa Astatement, Aand Athen Ait Abegins Ato Acheck Aif Ait Aends Aafter Athe Afirst Aexecution Aonly. AFollow Athe Afollowing Asteps:

let AyourName;

do A{

yourName A= Aprompt("Who Aare Ayou?");

} Awhile A(! AyourName);

console.log(yourName);

A

A

for loops

A Alot Aof Aloops Afollow Athe Awhile Aloop Apattern, Acreating Aa Acounter Abinding Ato Atrack Athe Aloop's Aprogress. AThen Aa Awhile Aloop Awith Aa Atest Aexpression Ato Asee Aif Athe Acounter Areaches Athe Aset Avalue.

for A(let Anumber A= A0; Anumber A<= A10; Anumber A= Anumber A+ A4) A{

console.log(number);

}

// A→ A0

// A→ A4

// Aetc

The Aparentheses Amust Aconsist Aof Atwo Asemicolons Aafter Athe Akeyword, Athe Afirst Apart Athat Ais Abefore Athe Afirst Asemicolon Aseparates Athe Aloop Aby Adescribing Aa Abinding. AThe Aother Apart Ais Athe Astatement Athat Adetermines Aif Athe Aloop Ashould Acontinue. AHere Ais Athe Acode Athat Aevaluate A210 Ausing Afor Ainstead Aof Awhile:

let Aresult A= A1;

for A(let Acounter A= A0; Acounter A< A10; Acounter A= Acounter A+ A1) A{

result A= Aresult A* A2;

}

console.log(result);

// A→ A1024

Breaking AOut Aof Aa ALoop

There Aare Aother Aways Ato Aend Aa Aloop Aother Athan Amaking Aa Alooping Acondition Agive Aa Afalse. ABreak Acan Ainfluence Ajumping Aout Aof Athe Aconfined Aloop. AThe Abreak Astatement Aevaluates Athis Aprogram Aif Athe Afirst Anumber, Awhich Ais Aboth Agreater Athan Aor Aequal Ato A20, Aand Acan Abe Adivided Aby A7.

for A(let Acurrent A= A20; Acurrent A= Acurrent A+ A1) A{

if A(current A% A7 A== A0) A{

console.log(current);

break;

}

}

// A→ A21

The A(%) Aoperator Ais Aused Ato Acheck Aif Aa Anumber Acan Abe Adivided Aby Aanother Anumber. AIf Ait Acan Abe Adivided, Athen Athe Aremaining Adivision Ais Azero. AThe Afor Ain Athe Aexample Ais Anot Achecked Aat Athe Aend Aof Athe Aloop, Awhich Ameans Auntil Athe Abreak Astatement Ainside Ais Aimplemented Athe Aloop Abecomes Ainfinite Aand Anever Astops.

Updating Abindings Asuccinctly

When Ayou Aare Ain Aa Aloop, Aprograms Awill Aupdate Aa Abinding Aregularly Ato Astore Aa Avalue Abased Aon Aits Aprevious Avalue.

counter A= Acounter A+ A1;

JavaScript Aoffers Aa Ashortcut.

counter A+= A1;

Related Ashortcuts Afunction Afor Aseveral Aother Aoperators, Alike Aresult A*= A2 Ato Amultiply Aresult Aor Acounter A-= A1 Ato Acount Ain Adescending Aorder.

This Aenables Aus Ato Aminimize Aour Acounting Aexample.

for A(let Anumber A= A0; Anumber A<= A12; Anumber A+= A2) A{

console.log(number);

}

For Acounter A+= A1 Aand Acounter A-= A1, Ahere Aare Ashorter Aequivalents:

counter++ Aand Acounter--.

Dispatching Aon Aa Avalue Awith Aswitch

Dispatching Aon Aa Avalue Awith Aswitch ACodes Acan Alook Alike Athis:

if A(x A== A"value1") Aaction1();

else Aif A(x A== A"value2") Aaction2();

else Aif A(x A== A"value3") Aaction3();

else AdefaultAction();

The Aswitch Ais Aused Ato Aexpress Athe Aabove Aform Aof Adispatch Astraightforwardly. ABelow Ais Aa Agood Aexample:

switch A(prompt("What Ais Athe Aatmosphere Alike?")) A{

case A"rainy":

console.log("Do Anot Aforget Ato Acome Awith Aan Aumbrella.");

break;

case A"sunny":

console.log("Be Alight Awith Ayour Adressing.");

case A"cloudy":

console.log("Move Aout.");

break;

default:

console.log("Weather Atype AUnknown!");

break;

}

Capitalization

Names Abinding Ado Anot Aallow Aspaces, Abut Ait Asupports Athe Ausage Aof Aseveral Awords Ato Adefine Athe Abinding Avalues. AHere Aare Aa Afew Atypes Athat Acan Abe Autilized Awhen Abinding Anames Awith Adifferent Awords:

fuzzylittleturtle

fuzzy_little_turtle

FuzzyLittleTurtle

fuzzyLittleTurtle

Comments

Sometimes Araw Acodes Ado Anot Atransmit Aevery Asingle Apiece Aof Ainformation Athat Ayou Awant Athe Aprogram Ato Asend Ato Areaders Aor Aspreads Athe Amessage Ain Aa Away Apeople Awill Afind Ait Ahard Ato Adecipher. AOther Atimes Ayou Afeel Alike Ayou Ashould Aattach Asome Asimilar Athoughts Ato Ayour Aprogram, Athe Acomment Aperforms Athis Afunction. AA Acomment Ais Aa Abit Achunk Aof Athe Atext Acontained Ain Aa Aprogram, Abut Athe Acomputer Aignores Ait. ATo Acode Aa Asingle Aline Acomment, Ause Athe Atwo Aslash Acharacters A(//), Afollowed Aby Athe Acomment Atext.

let AaccountBalance A= AcalculateBalance(account);

// AIt's Aa Ayellow-orange Aon Athe Amango Atree AaccountBalance.adjust();

// ACatching Agreen Atatters Ain Aour Ahome. Alet Areport A= Anew AReport();

// AWhere Athe Asun Aand Athe Amoon Ameets: AaddToReport(accountBalance, Areport);

// AIt's Aa Alarge Ahallway, Aand Athe Alights Aare Aquite Aamazing.

A A// Acomment Aappears Aonly Aat Athe Aend Aof Athe Aline. AAny Atext Awithin A/* Aand A*/ Aignore Ait, Aand Ait Adoes Anot Amatter Aif Ait Acontains Aline Abreaks. AIt Ais Aused Ato Aattach Ablocks Aof Ainformation Aabout Aa Aprogram Aor Afile.

Summary

Now Ayou Aunderstand Athat Ayou Acan Adevelop Aa Aprogram Athrough Athe Ause Aof Astatements, Awhich Astatement Aitself Acan Acontain Aseveral Astatements. AStatements Aconsist Aof Aexpressions, Aand Ayou Acan Acreate Aexpressions Athrough Asmaller Aexpressions. ASetting Astatements Aafter Aeach Aanother Aprovides Aan Aexecuted Aprogram Afrom Atop Ato Abottom. ADisturbances Acan Aalso Acome Ainto Athe Aflow Aof Ainfluence Athrough Aconditional A(if, Aelse, Aand Aswitch) Aand Alooping A(while, Ado, Aand Afor) Astatements. AAnd Awe Atouched Abindings, Athey Acategorize Abits Aof Adata Aunder Aa Aname, Aand Athey Acan Aalso Atrack Astate Awithin Athe Aprogram. AThe Adefined Abindings Aenjoy Athe Aenvironment Abetter. AWe Aalso Atouched Aon Athe Afunctions Asection Abeing Aunique Avalues Athat Asummarize Aa Apiece Aof Aprogram. AYou Acan Acall Athem Aby Atyping AfunctionName(argument1, Aargument2). AThis Atype Aof Afunction Acall Ais Aan Aexpression Aand Acan Aprovide Avalue.

Exercise

Write Aa AJavaScript Aprogram Athat Adisplays Athe Alarger Aand Aaccepts Adouble Aintegers.

Solution

It Ais Aimportant Ato Aknow Athat Ayou Acan Awrite A.length Aat Athe Aend Aof Aa Astring Ato Afind Aits Alength.

let Aabc A= A"abc";

console.log(abc.length);

// A→ A3

Chapter 4: Functions

Functions Aare Athe Aalpha Aand Aomega Aof AJavaScript Aprogramming Alanguage. AThe Aconcept Aof Aenclosing Aa Abit Aof Aprogram Acontained Ain Avalue Ahas Aa Alot Aof Aadvantages. AIt Aprovides Aa Away Ato Aorganize Amore Aprominent Aprograms, Ato Aminimize Arepetition, Arelate Anames Awith Asubprograms, Aand Aseparate Aprograms Afrom Athemselves. AFunctions Aare Aused Ato Adescribe Anew Awords.

Defining Aa Afunction

A Afunction Ais Aa Asystematic Abinding Awhereby Aa Afunction Adefines Athe Abinding Avalue. AThe Acode Abelow Aindicates Aa Afunction Athat Aprovides Athe Asquare Aof Aa Astated Anumber:

const Asquare A= Afunction(x) A{

return Ax A* Ax;

};

console.log(square(12));

// A→ A144

Create Aa Afunction Awith Aan Aexpression Athat Abegins Awith Athe Akeyboard Afunction. AFunctions Aconsists Aof Aa Abody Aand Aa Aset Aof Aparameters Athat Aaccommodates Athe Ayet Ato Abe Aexecuted Astatements Awhen Ayou Acall Aa Afunction. AThe Afunction Abody Ashould Aalways Abe Aenclosed Ain Abraces, Aeven Awhen Ait Ais Ajust Aan Aindividual Astatement. AA Afunction Acan Acontain Aseveral Aparameters Aor Azero Aparameter. AIn Athe Abelow Aexample, AmakeNoise Acontains Ano Aparameter Anames Aand Apower Aconsists Aof Atwo:

const AmakeNoise A= Afunction() A{

console.log("Pling!");

};

makeNoise();

// A→ APling!

const Apower A= Afunction(base, Aexponent) A{

let Aresult A= A1;

for A(let Acount A= A0; Acount A< Aexponent; Acount++) A{

result A*= Abase;

}

return Aresult;

};

console.log(power(2, A10));

// A→ A1024

Some Afunctions Acan Acreate Avalues Asuch Aas Asquare Aand Apower Awhile Asome Aresults Aonly Ainto Aa Aside Aeffect. AA Areturn Akeyword Athat Adoes Anot Acontain Aan Aexpression Aat Athe Aend Awill Abe Areturned Aas Aundefined.

Bindings Aand Ascopes

Every Abinding Aconsists Aof Aa Ascope Athat Aenables Athe Avisibility Aof Athe Abinding. AWhenever Ayou Acall Aa Afunction, Anew Aillustrations Aof Abinding Aare Adeveloped. AThis Acreates Aseparation Abetween Afunctions, Aevery Afunction Acall Abehaves Ain Aits Aown Aworld Aand Ais Aeasy Ato Aunderstand. AFunctions Athat Awere Adeclared Awith Athe Avar Akeyword Ain Athe Apre-2015 AJavaScript Aand Acan Abe Aseen Athroughout Athe Aglobal Ascope. AThey Aare Aabsent Ain Aa Afunction.

let Ax A= A10;

if A(true) A{

let Ay A= A20;

var Az A= A30;

console.log(x A+ Ay A+ Az);

// A→ A60

}

// Ay Ais Anot Avisible Ahere

console.log(x A+ Az);

// A→ A40

Nested Ascope

JavaScript Adifferentiate Abetween Athe Aglobal Aand Alocal Abindings. AYou Acan Acreate Ablock Aand Afunctions Awithin Athe Aother Afunctions Aand Ablocks Amanufacturing Aseveral Adegrees Aof Alocality. AFor Ainstance, Athis Afunction Aproduces Athe Aneeded Acomponents Ato Amake Aa Agroup Ahummus Acontains Aanother Afunction Awithin Ait:

const Ahummus A= Afunction(factor) A{

const Aingredient A= Afunction(amount, Aunit, Aname) A{

let AingredientAmount A= Aamount A* Afactor;

if A(ingredientAmount A> A1) A{

unit A+= A"s";

}

console.log(`${ingredientAmount} A${unit} A${name}`);

};

ingredient(1, A"can", A"chickpeas");

ingredient(0.25, A"cup", A"tahini");

ingredient(0.25, A"cup", A"lemon Ajuice");

ingredient(1, A"clove", A"garlic");

ingredient(2, A"tablespoon", A"olive Aoil");

ingredient(0.5, A"teaspoon", A"cumin");

};

The Acode Awithin Athe Acomponent Afunction Acan Aaccess Athe Afactor Abinding Afrom Athe Aouter Afunction. AThe Aset Aof Abindings Aaccessible Awithin Aa Ablock Ais Adecided Aby Athe Ablock Aposition Ain Athe Aprogram Atext. AEvery Alocal Ascope Acan Aaccess Athe Acontained Alocal Ascope Aand Aevery Ascope Acan Aas Awell Aaccess Athe Aglobal Ascope. AThis Aconcept Ais Anamed Alexical Ascoping.

Functions Aas Avalues

A Afunction Abinding Aoften Abehaves Aas Aa Aname Afor Aa Aparticular Ablock Aof Aprogram. AThis Atype Aof Abinding Adoes Anot Achange Abecause Ait Ais Adefined. AFunctions Acan Abe Aused Ain Aarbitrary Aexpressions Aas Awell Aas Aused Ato Asave Aa Afunction Avalue Ainto Aa Anew Abinding. AA Abinding Athat Astores Aa Afunction Ais Aa Asystematic Abinding Aand Aa Anew Avalue Acan Abe Aassigned Alike:

let AlaunchMissiles A= Afunction() A{

missileSystem.launch("now");

};

if A(safeMode) A{

launchMissiles A= Afunction() A{/* Ado Anothing A*/};

}

Declaration Anotation

There Ais Aa Alittle Away Ato Agenerate Aa Afunction Abinding. AWhen Ayou Ause Athe Afunction Akeyword Aat Athe Abeginning Aof Aa Astatement, Ait Awill Afunction Adifferently.

function Asquare(x) A{

return Ax A* Ax;

}

This Astatement Adescribes Athe Abinding Asquare Aand Adirects Ait Aat Aa Astated Afunction. AThis Atype Aof Afunction Adefinition Aconsists Aof Aone Aprecision.

console.log("My Amind Atells Ame Aevery Atime:", Afuture());

function Afuture() A{

return A"Ill Asurpass ABill AGates";

}

Arrow Afunctions

Functions Acontains Aa Athird Anotation Athat Adoes Anot Alook Aidentical Ato Athe Aothers. AYou Acan Ause Athe Aarrow A(=>) Aas Aan Aalternative Ato Athe Afunction Akeyword. AThe Aarrow A(=>) Acontains Aan Aequal Asign Aand Athe Agreater Athan Acharacter.

const Apower A= A(base, Aexponent) A=> A{

let Aresult A= A1;

for A(let Acount A= A0; Acount A< Aexponent; Acount++) A{

result A*= Abase;

}

return Aresult;

};

If Ayou Ahave Ajust Aone Aparameter Aname, Aexclude Athe Aparentheses Asurrounding Athe Aparameter Alist. ASometimes Athe Abody Ais Aa Asingle Aexpression Ainstead Aof Aa Ablock Aof Abraces, Ataking Aback Athe Aexpression Afrom Athe Afunction. ATherefore, Asquare Adefinitions Aperform Athe Asame Atask.

const Asquare1 A= A(x) A=> A{return Ax A* Ax;};

const Asquare2 A= Ax A=> Ax A* Ax;

When Athere Ais Ano Aparameter Aon Aan Aarrow Afunction, Aits Aparameter Alist Abecomes Aa Aset Aof Aunoccupied Aand Aineffective Aparentheses.

const Ahorn A= A() A=> A{

console.log("Toot");

};

You Adon’t Ahave Ato Ause Aboth Athe Afunction Aexpressions Aand Aarrow Afunctions Ain Athe Alanguage, Athey Aoffer Aand Aperform Athe Asame Aoperations.

The Acall Astacks

Let Aus Atake Asome Atime Ato Asee Ahow Acontrol Agoes Athrough Afunctions. ABelow Ais Aa Asimple Aprogram Amaking Afew Afunction Acalls:

function Agreet(who) A{

console.log("Hello A" A+ Awho);

}

greet("Harry");

console.log("Bye");

The Agreetings Acall Ainfluences Ato Acontrol Ato Ajump Ato Athe Abeginning Aof Athe Afunction. AThe Afunction Acall Aconsole.log Agets Aits Ajob Adone Aand Aseize Acontrol, Aand Athen Asend Acontrol Aback Ato Athe Afunction. AThe Afunction Acycle Aends Athere Aand Atransfers Aback Ato Athe Aplace Athat Acalls Ait. AThe Aflow Aof Acontrol Ais Abelow:

not Ain Afunction

in Agreet

in Aconsole.log

in Agreet

not Ain Afunction

in Aconsole.log

not Ain Afunction

The Acomputer Ahas Ato Arecollect Athe Acontext Ain Awhich Athe Acall Asequences Aoccurred Abecause Afunctions Ago Aback Ato Awhere Ait's Acalled Aposition. AWhen AConsole.log Acompletes, Ait Amust Areturn Ato Athe Aend Aof Athe Aprogram. AA Acall Astack Ais Aa Aplace Awhere Athe Acomputer Astores Athis Acontext. AWhenever Ayou Acall Aa Afunction, Athe Apresent Acontext Asaves Aat Athe Atop Aof Athis Astack. ABy Athe Atime Aa Afunction Agoes Aback, Ait Aeradicates Athe Atop Acontext Aand Autilizes Athe Acontent Afor Acontinual Aexecution.

The Astack Aneeds Aspace Ato Abe Asaved Ainto Awithin Athe Acomputer Amemory. AThe Abelow Acode Aexplains Athis Aby Aquerying Athe Acomputer Athat Acreates Azero Alimitation Abetween Atwo Afunctions Aback Aand Aforth.

function Achicken() A{

return Aegg();

}

function Aegg() A{

return Achicken();

}

console.log(chicken() A+ A" Acame Afirst.");

// A→ A??

Optional AArguments

The Abelow Acode Afunctions Aproperly Awithout Ainterference:

function Asquare(x) A{return Ax A* Ax;}

console.log(square(4, Atrue, A"hedgehog"));

// A→ A16

The Asquare Ais Adescribed Awith Ajust Aone Aparameter Aand Awe Acall Ait Athree. AThat Ais Apossible Abecause Athe Aprogramming Alanguage Adisregards Athe Asurplus Aarguments Aand Arecognizes Athe Asquare Aof Athe Afirst Aone. AJavaScript Ais Avery Atolerant Aabout Athe Aamount Aof Aarguments Abeing Apassed Ato Aa Afunction. AThe Agood Aside Aof Athis Acharacter Ais Athat Ait Aenables Acalling Afunctions Awith Aseparate Anumbers Aof Aarguments:

function Aminus(a, Ab) A{

if A(b A=== Aundefined) Areturn A-a;

else Areturn Aa A- Ab;

}

console.log(minus(10));

// A→ A-10

console.log(minus(10, A5));

// A→ A5

When Aan A= Aoperator Ais Awritten Aafter Aa Aparameter Aand Aan Aexpression, Athe Aexpression Avalue Awill Arestore Athe Anon-specified Aargument. AIf Ayou Awant Ato Apass Aand Anot Aproduce Athe Asecond Aargument, Athe Adefault Abecomes Atwo Aand Athe Afunction Aacts Alike Aa Asquare.

function Apower(base, Aexponent A= A2) A{

let Aresult A= A1;

for A(let Acount A= A0; Acount A< Aexponent; Acount++) A{

result A*= Abase;

}

return Aresult;

}

console.log(power(4));

// A→ A16

console.log(power(2, A6));

// A→ A64

Closure

The Acapability Ato Ause Afunctions Aas Avalues Ais Acoupled Awith Athe Afact Athat Alocal Abindings Aare Acreated Aagain Awhenever Ayou Acall Aa Afunction. AThe Abelow Acode Adisplays Athis Aexample; Ait Adescribes Aa Awrap Avalue, Aa Afunction Athat Adevelops Aa Alocal Abinding Aand Athen Asends Aback Aa Afunction Athat Aenters Aand Areturns Athe Alocal Abinding.

function AwrapValue(n) A{

let Alocal A= An;

return A() A=> Alocal;

}

let Awrap1 A= AwrapValue(1);

let Awrap2 A= AwrapValue(2);

console.log(wrap1());

// A→ A1

console.log(wrap2());

// A→ A2

This Aconcept Ais Acalled Aclosure. AIt Agives Athe Auser Athe Aability Ato Areference Aa Aparticular Ainstance Aof Aa Alocal Abinding Awithin Aa Aconfining Ascope. AAdding Aa Afew Achanges, Aour Aprevious Aexample Acan Aturn Ainto Aa Away Ato Adevelop Afunctions Athat Aaccumulates Aby Aan Aarbitrary Aamount.

function Amultiplier(factor) A{

return Anumber A=> Anumber A* Afactor;

}

let Atwice A= Amultiplier(2);

console.log(twice(5));

// A→ A10

Recursion

A Afunction Acan Acall Aitself Abut Ashould Anot Acall Aitself Aregularly Ato Aavoid Astack Aoverflow. ARecursive Afunction Ais Aa Afunction Athat Acalls Aitself. ARecursion Aenables Afew Afunctions Awritten Ain Aseparate Astyles. AFor Ainstance, Athe Abelow Acode Ais Athe Aexecution Aof Apower.

function Apower(base, Aexponent) A{

if A(exponent A== A0) A{

return A1;

} Aelse A{

return Abase A* Apower(base, Aexponent A- A1);

}

}

console.log(power(2, A3));

// A→ A8

There Ais Aone Aproblem Awith Athis Aexecution. AIt Ais Aslower Acompared Ato Aother Alooping Aversions. AUtilizing Aa Asingle Aloop Ais Aconsidered Alow Acost Athan Athe Amultiple Acalling Aof Afunctions. AAlthough Athat Adoes Anot Amake Arecursion Aan Aineffective Aoption Aof Alooping, Afew Aproblems Aare Asolved Awith Arecursion Aeasier Athan Awith Athe Ause Aof Aloops. AProblems Athat Aneed Ainspecting Aor Aprocessing Aseveral Abranches. ACheck Athis Aout: Awe Abegin Afrom Anumber A1 Aand Acontinuously Aadd A5 Aor Amultiply Aby A3. AFor Ainstance, Athe Anumber A13 Acan Abe Aobtained Aby Amultiplying Aby A3 Aand Athe Aaddition Aof A5 Atwice, Athereby Awe Acannot Aattain Athe A15. AThe Acode Ais Athe Arecursive Asolution:

function AfindSolution(target) A{

function Afind(current, Ahistory) A{

if A(current A== Atarget) A{

return Ahistory;

} Aelse Aif A(current A> Atarget) A{

return Anull;

} Aelse A{

return Afind(current A+ A5, A`(${history} A+ A5)`) A||

find(current A* A3, A`(${history} A* A3)`);

}

}

return Afind(1, A"1");

}

console.log(findSolution(24));

// A→ A(((1 A* A3) A+ A5) A* A3)

The Ainner Afunction Afind Atakes Atwo Aarguments, Athe Acurrent Anumber Aand Aa Astring Athat Adocuments Athe Aprocess Aof Aattaining Athis Anumber. AIf Aa Asolution Ais Afound, Ait Asends Aback Aa Astring Athat Adisplays Athe Aroute Ato Athe Atarget Aand Aif Ano Asolution Ais Afound, Athe Areturned Avalue Awill Abe Anull. ATo Aachieve Athis, Athe Afunction Aexecutes Aone Aof Athree Aactions. AIf Ayour Atarget Ais Athe Ais Athe Acurrent Anumber, Ayou Acan Aattain Athat Atarget Aby Ausing Athe Acurrent Ahistory Aso Ait Ais Asent Aback. ASometimes Athe Anumber Ais Alarger Athan Athe Atarget, Abut Ayou Ado Anot Aneed Ato Aexplore Athis Aoption Abecause Aaddition Aand Asubtraction Acan Aonly Aenlarge Athe Anumber Aso Ait Ais Asent Aback Aas Anull. AIf Ayou Aremain Abeneath Athe Atarget Anumber, Aboth Apaths Athat Abegin Athe Acurrent Anumber Ais Atried Aby Acalling Aitself Atwice, Aone Ato Aadd Aand Athe Aother Ato Amultiply. AIf Athe Afirst Acall Asends Asomething Avalid Aback Ain Areturn, Athen Agood, Aif Anot, Areturn Athe Asecond Acall, Ait Adoes Anot Amatter Awhether Aa Astring Aor Anull Ais Aprovided. ABelow Ais Aan Aillustration Aof Ahow Afunctions Aprovide Aeffects. AThis Aexample Asearches Afor Aa Aremedy Afor Athe Anumber A13.

find(1, A"1")

find(6, A"(1 A+ A5)")

find(11, A"((1 A+ A5) A+ A5)")

find(16, A"(((1 A+ A5) A+ A5) A+ A5)")

too Abig

find(33, A"(((1 A+ A5) A+ A5) A* A3)")

too Abig

find(18, A"((1 A+ A5) A* A3)")

too Abig

find(3, A"(1 A* A3)")

find(8, A"((1 A* A3) A+ A5)")

find(13, A"(((1 A* A3) A+ A5) A+ A5)")

found!

The Aindentation Aspecifies Aprofound Aof Athe Acall Astack.

Growing Afunctions

Functions Acan Abe Aintroduced Ainto Aprograms Ain Atwo Aways. AThe Afirst Ais Aby Awriting Asimilar Acodes Aa Alot Aof Atimes, Awhich Aenables Amore Amistakes Awhile Athe Asecond Ais Ato Asearch Afor Aa Afew Afunctionalities Athat Ahave Anot Abeen Awritten Aand Adeserves Aits Aown Afunction. AYou Acan Abegin Aby Anaming Athe Afunction Aand Awrite Athe Abody. ABelow Ais Aan Aexample. AWe Awill Awrite Aa Aprogram Athat Areproduce Atwo Anumbers–the Aamount Aof Achicken Aand Acows Aavailable Aon Aa Afarm.

007 ACows

011 AChickens

function AprintFarmInventory(cows, Achickens) A{

let AcowString A= AString(cows);

while A(cowString.length A< A3) A{

cowString A= A"0" A+ AcowString;

}

console.log(`${cowString} ACows`);

let AchickenString A= AString(chickens);

while A(chickenString.length A< A3) A{

chickenString A= A"0" A+ AchickenString;

}

console.log(`${chickenString} AChickens`);

}

printFarmInventory(7, A11);

Writing Alength Aafter Aa Astring Aexpression Adetermines Athe Alength Aof Athe Aparticular Astring. AThe Aloop Acontinues Ato Aadd Azeros Aat Athe Abeginning Aof Athe Anumber Astrings Auntil Athey Acomprise Aof Athree Acharacters.

Here Ais Aa Abetter Aattempt:

function AprintZeroPaddedWithLabel(number, Alabel) A{

let AnumberString A= AString(number);

while A(numberString.length A< A3) A{

numberString A= A"0" A+ AnumberString;

}

console.log(`${numberString} A${label}`);

}

function AprintFarmInventory(cows, Achickens, Apigs) A{

printZeroPaddedWithLabel(cows, A"Cows");

printZeroPaddedWithLabel(chickens, A"Chickens");

printZeroPaddedWithLabel(pigs, A"Pigs");

}

printFarmInventory(7, A11, A3);

Instead Aof Ataking Aout Athe Areplicated Apart Aof Athe Aprogram, Atry Ato Apick Aout Aan Aindividual Aconcept Awith Athe Afollowing Asteps:

function AzeroPad(number, Awidth) A{

let Astring A= AString(number);

while A(string.length A< Awidth) A{

string A= A"0" A+ Astring;

}

return Astring;

}

function AprintFarmInventory(cows, Achickens, Apigs) A{

console.log(`${zeroPad(cows, A3)} ACows`);

console.log(`${zeroPad(chickens, A3)} AChickens`);

console.log(`${zeroPad(pigs, A3)} APigs`);

}

printFarmInventory(7, A16, A3);

A Afunction Acan Aalso Abe Aused Ato Aprint Aaligned Atables Aof Anumbers.

Functions Aand Aside Aeffects

Functions Acan Aconsist Aof Aside Aeffects Aand Areturn Aa Avalue. AThey Adevelop Avalues Athat Aintegrate Aeasily Ain Anew Aways Amuch Amore Athan Afunctions Athat Aproduce Aside Aeffects. AA Apure Afunction Ais Aa Aunique Avalue Amanufacturing Afunction Athat Adoes Anot Adepend Aon Aeither Acode Aside Aeffects. AFor Ainstance, Ait Awill Anot Arecognize Aa Aglobal Abinding Awith Aa Achangeable Avalue. AIt Aalso Aconsists Aof Aa Acallable Aproperty Atogether Awith Athe Asame Aarguments Aand Aproduces Aequal Avalue.

Summary

In Athis Achapter, Ayou Anow Aunderstand Ahow Ato Awrite Ayour Afunctions. AKnowing Ahow Ato Awrite Athe Afunction Akeyword Aand Awhen Ato Ause Aan Aexpression, Ayou Acan Anow Abuild Aa Afunction Avalue. AWhen Ayou Ause Aa Afunction Aas Aa Astatement, Ait Acan Aset Aa Abinding Aand Aname Aa Afunction Ato Abe Aits Avalue. AYou Acan Aalso Ause Aarrow Afunctions Ato Abuild Afunctions.

// ADefine Af Ato Ahold Aa Afunction Avalue

const Af A= Afunction(a) A{

console.log(a A+ A2);

};

// ADeclare Ag Ato Abe Aa Afunction

function Ag(a, Ab) A{

return Aa A* Ab A* A3.5;

}

// AA Aless Averbose Afunction Avalue

let Ah A= Aa A=> Aa A% A3;

The Amajor Aperspective Aof Aunderstanding Afunctions Ais Aknowing Athe Ascopes. AEvery Ablock Abuilds Aa Anew Ascope. AParameters Aand Abindings Aset Ain Aa Aspecific Ascope Aare Alocal Aand Ainvisible Afrom Athe Aoutside. ABindings Aset Awith Avar Aact Adifferently, Aand Athey Aresult Ain Athe Aglobal Ascope. ADifferentiating Athe Atasks Athat Athe Aprogram Aexecutes Ainto Avarious Afunctions Ais Aimportant. AYou Ado Anot Aneed Ato Arepeat Ayourself Aoften, Aand Afunctions Acan Aarrange Aa Aprogram Aby Acategorizing Acode Ainto Abits Athat Aperform Aspecific Aactions.

Exercise

Write Aa AJavaScript Aprogram Ato Asee Aif Aa Anumber Ais Aeven Aor Anot.

Solution

A

Chapter 5: Data Structures: Objects and Arrays

Data Alayouts Adevelop Afrom ABooleans, Astrings, Aand Anumbers Afragments. ASeveral Atypes Aof Ainformation Ause Amore Athan Aone Achunk. AObjects Aenable Athe Auser Ato Acollate Avalues Atogether Awith Aother Aobjects Ato Adevelop Amore Acompound Alayouts. AIn Athis Achapter, Ayou Awill Aunderstand Athe Aconcepts Aof Asolving Aa Areal Aproblem Aat Ahand.

Data Asets

If Ayou Awant Ato Awork Awith Aa Alot Aof Adigital Adata, Ayou Amust Arepresent Athe Adigital Adata Ain Athe Amachine Amemory. AFor Ainstance, Ayou Aneed Ato Arepresent Aa Agroup Aof Anumbers Alike A2, A3, A5, A7, Aand A11. ANow Alet’s Aget Aprolific Awith Aour Ause Aof Astrings Aas Astrings Acan Acontain Aquite Aa Alot Aof Adata. AWe Awill Ause A2 A3 A5 A7 A11 Aas Athe Arepresentation. AJavaScript Aprogramming Alanguage Aoffers Aa Aunique Adata Atype Afor Asaving Asequences Aof Avalues, Awhich Ais Acalled Aan Aarray. AWrite Aan Aarray Aas Aa Alist Aof Avalues Awithin Athe Abetween Asquare Abrackets, Adifferentiated Aby Acommas.

let AlistOfNumbers A= A[2, A3, A5, A7, A11];

console.log(listOfNumbers[2]);

// A→ A5

console.log(listOfNumbers[0]);

// A→ A2

console.log(listOfNumbers[2 A- A1]);

// A→ A3

The Anotation Aused Ato Aget Aelements Awithin Aan Aarray Aalso Autilize Athe Asquare Abrackets. AA Acomplete Asquare Abrackets Apair Aright Aafter Aan Aexpression Athat Acontains Aanother Aexpression Awithin. AWhen Ayou Astart Acounting Aelements Ain Aan Aarray, Ayou Abegin Afrom Azero Aand Anot Aone. ATherefore Athe Afirst Aelement Ais Aredeemed Awith AlistOfNumbers[0].

Properties

The Aprevious Achapters Ahave Acontained Aexpressions Alike Athe AmyString. ALength A(to Acalculate Athe Alength Aof Aa Astring) Aand AMath.max A(the Amaximum Afunction). AThese Aare Aproperties Athat Acan Aapproach Athe Aproperty Avalues. AVirtually Aall AJavaScript Avalues Acontain Aproperties. AThe Afew Avalues Athat Ado Anot Acontain Aproperties Aare Anull Aand Aundefined. AIf Ayou Aaccess Aa Aproperty Awith Aa Anonvalue, Athe Aresult Awill Abe Aan Aerror.

null.length;

// A→ ATypeError: Anull Ahas Ano Aproperties

In AJavaScript, Athe Atwo Amajor Aways Ato Aevaluate Aproperties Aare Awith Aa Adot Aand Asquare Abrackets. AThe Avalue.x Aand Avalue[x] Acan Aevaluate Athe Aproperty Aon Avalue, Anot Aparticularly Athe Asame Aproperty. AHow Ayou Ause Ax Ais Adifferent Afrom Ahow Ayou Ause Aa Adot.

If Ayou Awant Ato Ause Athe Adot, Athe Atext Ayou Ainput Aafter Athe Adot Ais Athe Aname Aof Athe Aproperty. AAnd Aif Ayou're Agoing Ato Ause Athe Asquare Abrackets, Athe Aexpression Awithin Athe Abrackets Ais Aaccessed Ato Aredeem Athe Aproperty Aname. AValue.x Adelivers Athe Aproperty Aof Avalue Acalled A“x,” Awhile Avalue[x] Aaccesses Athe Aexpression Ax Aand Autilize Athe Aresult, Atransformed Ainto Aa Astring Aas Athe Aname Aof Athe Aproperty. AIf Athe Aproperty Ayou Awant Ais Anamed Acolor, Ayou Ashould Atype Avalue.color. AYou Acan Awithdraw Athe Aproperty Athat Athe Avalue Acalled Awithin Athe Abinding Ai, Atype Avalue[i]. AThe Aname Aof Aproperties Aare Astrings, Abut Athe Adot Anotation Aperforms Awith Aonly Avalid Abinding Anames. ATherefore Aif Ayou Awant Ato Aevaluate Aa Aproperty Anamed A2 Aor AJohn ADoe, Ause Athe Asquare Abrackets: Avalue[2] Aor Avalue["John ADoe"].

The Aelements Awithin Aan Aarray Asave Aas Athe Aproperties Aof Aan Aarray Athat Autilize Anumbers Aas Aproperty Anames. AAn Aarray's Alength Aproperty Adetermines Ahow Amany Aitems Ait Acontains. AThe Aname Aof Athat Aproperty Ais Aa Avalid, Abinding Aname. AType Aarray.length Ato Adetermine Athe Alength Aof Aan Aarray, Ait Ais Amuch Aeasier Ato Atype Athan Athe Aarray["length"].

Methods

The Astring Aand Aarray Aobjects Aaccommodate Aseveral Aproperties Athat Astore Afunction Avalues.

let Adoh A= A"Doh";

console.log(typeof Adoh.toUpperCase);

// A→ Afunction

console.log(doh.toUpperCase());

// A→ ADOH

Each Astring Aconsists Aof Aa AtoUpperCase Aproperty. AWhen Ayou Acall Athis Aproperty, Ait Asends Aback Aa Acopy Aof Athe Astring Awhereby Aall Athe Acontaining Aletters Atransform Ainto Auppercase. AAlthough Athe AtoUpperCase Ado Anot Ago Athrough Aan Aargument, Athe Afunction Acan Aevaluate Athe Astring A"Doh," Awhich Ais Athe Aproperty Aof Athe Avalue Awe Acalled Aabove. AProperties Athat Aconsist Aof Afunctions Aare Aknown Aas Amethods. AThe Abelow Aexample Aillustrates Atwo Amethods Athat Acan Abe Aused Ato Ainfluence Aarrays.

let Asequence A= A[1, A2, A3];

sequence.push(4);

sequence.push(5);

console.log(sequence);

// A→ A[1, A2, A3, A4, A5]

console.log(sequence.pop());

// A→ A5

console.log(sequence);

// A→ A[1, A2, A3, A4]

The Apush Amethod Ais Aused Ato Aattach Aa Avalue Ato Athe Aend Aof Aan Aarray Awhile Athe Apop Amethod Adoes Athe Adirect Aopposite. AIt Aeradicates Athe Alast Avalue Awithin Aan Aarray Aand Asends Ait Aback. AThese Aare Agenerational Aterms Aof Aoperations Aon Aa Astack. AA Astack Ais Aa Adata Alayout Athat Aenables Ausers Ato Apush Avalues Ain Aand Apop Athem Aout Ain Athe Aopposite Adirection Aso Athat Athe Aadded Avalue Awill Aremove Afirst.

Objects

You Acan Arepresent Aa Agroup Aof Alog Aentries Aas Aan Aarray Aalthough Aeach Astring Aentry Ais Arequired Ato Asave Aa Alist Aof Aactivities Aas Awell Aas Aa ABoolean Avalue Athat Aspecifies Aif AJacques Atransformed Ato Aa Asquirrel Aor Anot. AWe Awill Agroup Athis Ainto Aa Asingle Avalue Aand Aplace Athe Agrouped Avalues Awithin Aan Aarray Aof Alog Aentries. AArbitrary Acollections Aof Aproperties Aare Athe Avalue Aof Athe Atype Aobject. AWe Awill Adevelop Aan Aobject Autilizing Abraces Aas Aan Aexpression.

let Aday1 A= A{

squirrel: Afalse,

events: A["work", A"touched Atree", A"pizza", A"running"]

};

console.log(day1.squirrel);

// A→ Afalse

console.log(day1.wolf);

// A→ Aundefined

day1.wolf A= Afalse;

console.log(day1.wolf);

// A→ Afalse

The Abraces Acontain Aa Alist Aof Aproperties Adivided Aby Acommas. AEvery Aproperty Acontains Aa Aname Aaccompanied Aby Aa Avalue Aand Aa Acolon. AWhen Ayou Awrite Aan Aobject Aover Aseveral Alines, Amake Asure Ayour Aindenting Ais Agood Abecause Ait Aenables Abetter Areadability. AQuote AInvalid Abinding Anames Aproperties Aor Avalid Anumbers Ashould.

let Adescriptions A= A{

work: A"Went Ato Awork,"

"touched Atree": A"Touched Aa Atree."

};

You Acan Ause Abraces Ain Atwo Adifferent Aways Ain AJavaScript. AIt Ais Aused Aat Athe Abeginning Aof Aa Astatement Aand Acan Aalso Abe Autilized Ato Abegin Aa Ablock Aof Astatements. AYou Acan Aspecify Aa Avalue Ato Aa Aproperty Aexpression Ausing Athe A= Aoperator. AIt Atakes Athe Aplace Aof Athe Aproperty Avalue, Aand Aif Ait Ais Ain Aexistence, Ait Adevelops Aa Anew Aone. AThe Adelete Aoperator Ais Aa Aunary Aoperator Athat Aeradicates Athe Aproperty Aname Aof Aan Aobject. ABelow Ais Aan Aillustration:

let AanObject A= A{left: A1, Aright: A2};

console.log(anObject.left);

// A→ A1

delete AanObject.left;

console.log(anObject.left);

// A→ Aundefined

console.log("left" Ain AanObject);

// A→ Afalse

console.log("right" Ain AanObject);

// A→ Atrue

The Abinary Ain Aoperation Adetermines Aif Aan Aobject Aor Astring Acontains Aa Anamed Aproperty. AThe Amajor Adifferentiation Abetween Aspecifying Aa Aproperty Ato Aundefined Aand Adeleting Ait Ais Athat Athe Aobject Aconsists Aof Aa Aproperty Aand Athe Adeleting Adoes Anot Apossess Athe Aproperty, Aso Athe Avalue Areturns Aas Afalse. ATo Adetermine Awhat Aproperties Acontained Ain Aan Aobject Aand Asends Aback Aan Aarray Aof Astrings Awith Aproperty Anames Aof Athe Aobject.

console.log(Object.key({x: A0, Ay: A0, Ac: A2}));

// A→ A["x", A"y", A"c"]

The AObject.assign Afunction Ais Aused Ato Acopy Aproperties Afrom Aone Aobject Ato Aanother.

let AobjectA A= A{a: A1, Ab: A2};

Object.assign(objectA, A{b: A3, Ac: A4});

console.log(objectA);

// A→ A{a: A1, Ab: A3, Ac: A4}

An Aarray Ais Aa Aunique Aobject Aused Afor Asaving Asuccession Aof Athings. AWhen Ayou Aaccess Athe Atypeof A[], Ait Aprovides A"object." AThe Abelow Aillustration Astands Afor Athe Ajournal Athat AJacques Astores Aas Aan Aarray Aof Aobjects.

let Ajournal A= A[

{events: A["work", A"touched Atree", A"pizza",

"running", A"television"],

squirrel: Afalse},

{events: A["work", A"ice Acream", A"cauliflower",

"lasagna", A"touched Atree", A"brushed Ateeth"],

squirrel: Afalse},

{events: A["weekend", A"cycling", A"break", A"peanuts",

"beer"],

squirrel: Atrue},

/* Aand Aso Aon... A*/

];

Mutability

We Ahave Adiscussed Adifferent Avalues Asuch Aas ABooleans, Astrings, Aand Anumbers Awhose Avalues Aare Adifficult Ato Achange, Aalthough Athey Acan Abe Acombined Ato Aacquire Anew Avalues Afrom Athem. AObjects Aare Adifferent Afrom Avalues, Aand Ait Aenables Aproperty Achanging; Athey Acan Acreate Adifferent Acontent Afor Aa Asingle Aobject Avalue Aat Adifferent Atimes. AWhen Athere Aare Atwo Anumbers, A120 Aand A120, Athey Aare Aconsidered Athe Asame, Aand Athere Ais Aa Asimilarity Abetween Asetting Atwo Areferences Ato Aone Aobject Aand Apossessing Atwo Aseparate Aobjects Acontaining Athe Asame Aproperties. ACheck Athe Abelow Acode:

let Aobject1 A= A{value: A10};

let Aobject2 A= Aobject1;

let Aobject3 A= A{value: A10};

63

console.log(object1 A== Aobject2);

// A→ Atrue

console.log(object1 A== Aobject3);

// A→ Afalse

object1.value A= A15;

console.log(object2.value);

// A→ A15

console.log(object3.value);

// A→ A10

The Aobject1 Aand Aobject2 Abindings Ahold Athe Asame Aobject, Aand Athat Ais Awhy Aaltering Aobject1 Aone Ainfluences Athe Avalue Aof Aobject2. AThey Aare Aidentical Aby Anature. AThe Abinding Aobject3 Apoints Ato Aa Aseparate Aobject Athat Aconsists Aof Asimilar Aproperties Aas Athe Aobject1 Abut Ahas Aa Adifferent Alife. ABindings Acan Abe Aconstant Aor Achangeable, Abut Ait Adoes Anot Ainfluence Atheir Avalues. AA Aconst Abinding Aan Aobject Acannot Abe Atransformed Aand Arelentlessly Apointing Ato Athe Asame Aobject. AIt Ais Athe Aobject Acontents Athat Acan Abe Achanged.

const Ascore A= A{visitors: A0, Ahome: A0};

// AThis Ais Aokay

score.visitors A= A1;

// AThis Aisn't Aallowed

score A= A{visitors: A1, Ahome: A1};

When Athe AJavaScript’s A== Aoperator Ais Aused Ato Adifferentiate Aobjects, Ait Auses Athe Aidentity Ato Aperform Athat Atask. AIt Awill Atranslate Atrue Aif Athe Aobjects Acontain Athe Asame Avalue. ADifferentiating Aseveral Aobjects Awill Areturn Afalse, Aeven Aif Atheir Aproperties Aare Asimilar.

The Alycanthrope's Alog

So, Ayou Abegin Ayour AJavaScript Ainterpreter Aand Acreates Athe Aenvironment Ayou Aneed Ato Akeep Ayour Ajournal.

let Ajournal A= A[];

function AaddEntry(events, Asquirrel) A{

journal.push({events, Asquirrel});

}

Instead Aof Aproclaiming Aproperties Asuch Aas Aevents, Ait Asets Aa Aproperty Aname.

So Athen, Aat A10 Ap.m. Aevery Aevening Aor Aoccasionally Ain Athe Afollowing Amorning, Aafter

getting Adown Afrom Athe Atop Ashelf Aof Ayour Abookcase, Ayour Adaily Arecords.

addEntry(["work", A"touched Atree", A"pizza", A"running",

"television"], Afalse);

addEntry(["work", A"ice Acream", A"cauliflower", A"lasagna",

"touched Atree", A"brushed Ateeth"], Afalse);

addEntry(["weekend", A"cycling", A"break", A"peanuts",

"beer"], Atrue);

Correlation Ais Aan Aevaluation Aof Avulnerability Abetween Aanalytical Avariables. AThey Aare Aknown Aas Avalues Athat Aspan Afrom A-1 Ato A1. AAn AUnrelated Avariable Ais Acalled Aa Azero Acorrelation. AA Acorrelation Aof A1 Asignifies Athat Athe Atwo Aare Arelated. ANegative Ameans Athat Athe Avariables Aare Arelated Aperfectly Abut Aopposites Ato Aeach Aother; Aone Ais Atrue, Aand Athe Aother Ais Afalse. ATo Acalculate Athe Aevaluation Aof Athe Acorrelation Abetween Atwo ABoolean Avalues, Autilize Athe Aphi Acoefficient A(φ). AThis Aformula Ainput Ais Aa Afrequency Atable Aholding Athe Anumber Aof Atimes Ait Anotices Aseveral Amixtures Aof Athe Avariables. AThe Aformula's Aoutput Awill Abe Aa Anumber Abetween A-1 Aand A1. AThat Ais Athe Abest Adefinition Aof Aa Acorrelation.

Let Aus Ause Athe Aevent Aif Aeating Apizza Aas Aan Aexample Aand Ainsert Ait Ainto Aa Afrequency Atable Awhereby Aevery Anumber Asignifies Athe Atotal Aof Atimes, Aand Awe Aused Athe Acombination Ain Aour Ameasurements. AWe Aname Athe Atable An, Aand Awe Acalculate Aφ Awith Athe Abelow Aformula:

φ A=

n11n00 A− An10n01

√

n1•n0•n•1n•0

The Anotation An01 Asignifies Athe Anumber Aof Ameasurements Awhere Athe Afirst Avariable Aturns Afalse A(0), Aand Athe Asecond Avariable Abecomes Atrue A(1). AThe Apizza Atable, An01 Ais A9.

The Avalue An1• Aindicates Athe Asum Aof Aall Ameasurements Awhere Athe Afirst Avariable Aturns Atrue, Athat Ais A5 Ain Athe Atable Aexample. AAs Awell Aas An•0 Asuggests Athe Aquantity Aof Athe Ameasurements Awhere Athe Asecond Avariable Abecomes Afalse.

The Apizza Atable, Athe Atop Aof Athe Adivision Aline Awould Abe A1×76−4×9 A= A40, Aand Athe Abelow Apart Abelow Awould Abe Athe Asquare Aroot Aof A5×85×10×80, Aor A√340000. AThe Aresult Awill Abe Aφ A≈ A0.069, Awhich Ais Atiny. ATherefore, Aeating Apizza Ahad Ano Aimpact Aon Atransformations.

Computing Acorrelation

JavaScript Aenables Athe Arepresentation Aof Aa Atwo-by-two Atable Awith Afour Aelement Aarrays A([76, A9, A4, A1]). AOther Arepresentations Asuch Aas Aan Aarray Aholding Atwo Atwo-element A([[76, A9], A[4, A1]]) Aor Aan Aobject Acontaining Aproperty Anames Asuch Aas A"11" Aand A"01", Aand Athe Aflat Aarray, Awhich Aproduces Athe Aexpression Athat Aaccess Athe Achair Ashort. AWe Awill Aexplain Athe Aindices Ato Athe Aarray Aas Atwo-bit Abinary Anumbers, Awhere Athe Amost Asignificant Adigit Arefers Ato Athe Asquirrel Avariable Awhile Athe Aleast Asignificant Arefers Ato Athe Aevent Atable. AFor Ainstance, Athe Abinary Anumber A10 Arefers Ato Athe A"Jacques Adid Aturn Ainto Aa Asquirrel" Acase Abut Athe Aevents Adidn’t Aappear. AIt Aoccurred Afour Aties Aand Abinary Ais A2 Ain Adecimal, Athe Anumber Ais Astored Aas Aan Aindex A2 Aof Athe Aarray. AThis Afunction Acalculates Athe Aφ Acoefficient Afrom Aan Aarray:

function Aphi(chair) A{

return A(chair A[3] A* Achair A0] A- Achair A[2] A* Achair A[1]) A/

Math.sqrt((chair A[2] A+ Achair A[3]) A*

(chair A[0] A+ Achair A[1]) A*

(chair A[1] A+ Achair A[3]) A*

(chair A[0] A+ Achair A[2]));

}

console.log(phi([76, A9, A4, A1]));

// A→ A0.068599434

The Atable Arequires Atwo Afields Ato Aacquire Afields Alike An1• Abecause Athe Atotal Anumber Aof Arows Aand Acolumns Aare Astored Aindirectly Ainto Aour Adata Alayout. AIf Ayou Awant Ato Aextract Aa Atwo-by-two Atable Afor Aa Aparticular Aevent, Ayou Amust Aloop Aacross Aall Athe Aentries Aand Acalculate Athe Anumber Aof Atimes Athe Aevent Ahappened Ato Athe Asquirrel Atransformations.

function AtableFor(event, Ajournal) A{

let Atable A= A[0, A0, A0, A0];

for A(let Ai A= A0; Ai A< Ajournal.length; Ai++) A{

let Aentry A= Ajournal[i], Aindex A= A0;

if A(entry.events.includes(event)) Aindex A+= A1;

if A(entry.squirrel) Aindex A+= A2;

table[index] A+= A1;

}

return Atable;

}

console.log(tableFor("pizza", AJOURNAL));

// A→ A[76, A9, A4, A1]

Arrays Aconsists Aof Aan Ainclude Amethod, Awhich Ais Aused Ato Acheck Aif Aa Aset Avalue Aexists Ain Athe Aarray. AThis Amethod Ais Aused Aby Athe Afunction Ato Adecide Aif Athe Aevent Aname Ais Ainterested Athe Astated Aevent Alist Afor Aa Agiven Aday.

Array Aloops

The AtableFor Afunction Acontains Aa Aloop Alike Athis:

for A(let AI A= A0; AI A< AJOURNAL.length; AI++) A{

let Aentry A= AJOURNAL[i];

// ADo Asomething Awith Aentry

}

This Atype Aof Aloop Ais Aused Ain Ahigh-level AJavaScript

This Ais Ahow Ato Awrite Athat Atype Aof Aloop Ain Amodern AJavaScript.

for A(entrance Aof AJOURNAL) A{

console.log(`${entrance.events.length} Aevents.`);

}

With Aa Aloop Alike Athis, Athe Aloop Acontinues Aacross Athe Aelements Aof Athe Avalue Aspecified Aafter Aof. AThis Aloop Ais Aused Afor Astrings Aand Aother Adata Alayouts.

The Afinal Aanalysis

A Acorrelation Ais Acalculated Afor Aevery Atype Aof Aevent Athat Ahappens Ain Athe Adata Aset. AIf Ayou Awant Ato Aachieve Athat, Asearch Aevery Atype Aof Aevent.

function AjournalEvents(journal) A{let Aevents A= A[];

for A(let Aentry Aof Ajournal) A{

for A(let Aevent Aof Aentry.events) A{

if A(!events.includes(event)) A{

events.push(event);

}

}

}

return Aevents;

}

console.log(journalEvents(JOURNAL));

// A→ A["carrot", A"exercise", A"weekend", A"bread", A…]

By Amoving Aacross Aevery Aevent Aand Amaking Aadditions Ato Athose Athat Aare Anot Ain Athe Aevents Aarray, Athis Afunction Agathers Aall Athe Atype Aof Aevent.

A Alot Aof Acorrelations Aappear Ato Alie Aclose Ato Azero. AEating Abread, Acarrots Aor Apudding Adoes Anot Aactivate Athe Asquirrel-lycanthropy. AIt Ahappens Aoften Aduring Athe Aweekends. AUsing Athat, Abelow Aare Aall Athe Acorrelations.

for A(let Aevent Aof AjournalEvents(JOURNAL)) A{

console.log(event A+ A":", Aphi(tableFor(event, AJOURNAL)));

}

// A→ Acarrot: A0.0140970969

// A→ Aexercise: A0.0685994341

// A→ Aweekend: A0.1371988681

// A→ Abread: A-0.0757554019

// A→ Apudding: A-0.0648203724

// Aand Aso Aon...

let Aus Afilter Aresults Ato Adisplay Aonly Acorrelations Athat Aare Agreater Athan A0.1 Aor Aless Athan A-0.1.

for A(let Aevent Aof AjournalEvents(JOURNAL)) A{

let Acorrelation A= Aphi(tableFor(event, AJOURNAL));

if A(correlation A> A0.1 A|| Acorrelation A< A-0.1) A{

console.log(event A+ A":", Acorrelation);

}

}

// A→ Aweekend: A0.1371988681

// A→ Abrushed Ateeth: A-0.3805211953

// A→ Acandy: A0.1296407447

// A→ Awork: A-0.1371988681

// A→ Aspaghetti: A0.2425356250

// A→ Areading: A0.1106828054

// A→ Apeanuts: A0.5902679812

In Aa Acorrelation Afactors, Aone Ais Astronger Athan Athe Aother. AEating Apeanuts Ahas Aa Apowerful Achance Aof Atransforming Ainto Aa Asquirrel, Athereby Abrushing Athe Ateeth Ahas Aa Anotable Anegative Aeffect. AHere's Asomething:

for A(let Aentry Aof AJOURNAL) A{

if A(entry.events.includes("peanuts") A&&

!entry.events.includes("brushed Ateeth")) A{

entry.events.push("peanut Ateeth");

}

}

console.log(phi(tableFor("peanut Ateeth", AJOURNAL)));

// A→ A1

Further Aarrayology

Here Aare Aa Afew Amore Aobject-related Aconcepts Ayou Ashould Aknow. AWe Abegin Awith Athe Ause Aof Asome Auseful Amethods Aof Aan Aarray.

The Aadding Aand Aremoving Aof Amethods Athings Aat Athe Abeginning Aof Aan Aarray Aare Acalled Aunshift Aand Ashift.

let AtodoList A= A[];

function Aremember(task) A{

todoList.push(task);

}

function AgetTask() A{

return AtodoList.shift();

}

function ArememberUrgently(task) A{

todoList.unshift(task);

}

The Aabove Aprogram Aorganizes Aa Achain Aof Atasks. AYou Acan Aadd Atasks Ato Athe Aend Aof Athe Aqueue Aby Acalling Aremember("groceries"), Aand Awhen Ayou Awant Ato Aget Asomething Adone, Acall AgetTask() Ato Aget A(and Aremove) Aitem Afrom Athe Aqueue. AIf Ayou Awant Ato Asearch Afor Aa Aparticular Avalue, Aarrays Asupply Aan AindexOf Amethod. AThe Amethod Afinds Aits Away Athrough Athe Aarray Afrom Athe Abeginning Ato Athe Aend Aand Asends Aback Athe Aindex Athe Avalue Arequested, Aif Ait Awas Afound Ait Areturns A—or A-1 Aif Ait Awasn’t Afound. ATo Asearch Afrom Athe Abeginning Ato Athe Aend, Ause Athe AlastIndexOf Amethod.

console.log([1, A2, A3, A2, A4].indexOf(3));

// A→ A1

console.log([1, A2, A3, A2, A4].lastIndexOf(3));

// A→ A3

The AindexOf Aand AlastIndexOf Atakes Aa Avoluntary Aargument Athat Aspecifies Awhere Athe Asearch Abegins. AAnother Agreat Amethod Ais Athe Aslice, Athis Amethod Abegins Aand Aends Athe Aindices Aand Asend Aback Aan Aarray Acontaining Athree Aelements. AThe Abeginning Ais Ainclusive Awhile Athe Aend Ais Aexclusive.

console.log([0, A1, A2, A3, A5].slice(2, A4));

// A→ A[2, A3]

console.log([0, A1, A2, A3, A5].slice(2));

// A→ A[2, A3, A5]

If Athe Aend Aindex Ais Anot Astated, Aslice Atake Aall Athe Aelements Aafter Athe Astart Aindex. AYou Acan Ause Athe Aconcat Amethod Ato Aglue Aarrays Atogether Ato Aproduce Aa Anew Aarray. AThe Abelow Aexample Adisplays Aconcat Aand Aslice Ain Aaction.

function Aremove(arrays, Aindex) A{

return Aarray.slice(0, Aindex)

.concat(arrays.slice(index A+ A1));

}

console.log(remove(["a", A"k", A"c", A"f", A"e"], A2));

// A→ A["a", A"k", A"f", A"e"]

Strings Aand Atheir Aproperties

During Athe Astring Avalue Achapter, Awe Adiscussed Alength Aand AtoUpperCase Abut Aif Ayou Awant Ato Aadd Aa Anew Aproperty, Ait Adoes Anot Astick.

let Akim A= A"Kim";

kim.age A= A88;

console.log(kim.age);

// A→ Aundefined

All Astrings Avalue Acontains Aa Afew Amethods. ASome Aare Athe Aslice Aand AindexOf Awhich Ahave Aa Asimilar Aappearance Aof Aarray Amethods Aas Awell Aas Athe Aname.

console.log("coconuts”. ASlice(4, A7));

// A→ Anut

console.log("coconut”.indexOf("u"));

// A→ A5

A Astring’s AindexOf Acan Alook Afor Aa Astring Aholding Amore Athan Aone Acharacter, Awhile Athe Acorresponding Aarray Amethod Asearch Afor Aa Asingle Aelement.

console.log("one Atwo Athree".indexOf("ee"));

// A→ A11

The Atrim Amethod Aeradicates Awhitespace Afrom Athe Abeginning Ato Athe Aend Aof Aa Astring.

console.log(" Aokay A\n A".trim());

// A→ Aokay

The AzeroPad Afunction Acan Aalso Abe Acalled Aa ApadStart, Ait Atakes Athe Apreferred Apadding Aand Alength Acharacter Aas Aarguments.

console.log(String(6).padStart(3, A"0"));

// A→ A006

You Acan Abreak Aa Astring Aon Aevery Adevelopment Aof Aanother Astring Awith Asplit Aand Athen Ajoin Athem Atogether Awith Ajoin.

let Asentence A= A"Secretarybirds Aspecialize Ain Astomping";

let Awords A= Asentence.split(" A");

console.log(words);

// A→ A["Secretarybirds", A"specialize", A"in", A"stomping"]

console.log(words.join(". A"));

// A→ ASecretarybirds. Aspecialize. Ain. Astomping

You Acan Ause Athe Arepeat Amethod Ato Arepeat Aa Astring, Awhich Adevelops Aa Anew Astring Aholding Aseveral Acopies Aof Athe Aoriginal Astring Aattached Atogether.

console.log("LA".repeat(3));

// A→ ALALALA

If Ayou Awant Ato Aaccess Aindividual Acharacters Ain Aa Astring. Alook Abelow:

let Astring A= A"ABC";

console.log(string.length);

// A→ A3

console.log(string[1]);

// A→ Ab

Rest Aparameters

It Ais Aimportant Afor Aa Afunction Ato Areceive Aany Anumber Aof Aarguments. AIf Ayou Awant Ato Awrite Asuch Aa Afunction, Aadd Athree Adots Abefore Athe Alast Aparameter Aof Athe Afunction.

function Amax A(...numbers) A{

let Aresult A= A-Infinity;

for A(let Anumber Aof Anumbers) A{

if A(number A> Aresult) Aresult A= Anumber;

}

return Aresult;

}

console.log(max(4, A1, A9, A-2));

// A→ A9

When Ayou Acall Aa Afunction, Athe Arest Aof Athe Aparameters Abelongs Ato Aan Aarray Aholding Athe Arest Aof Athe Aarguments. AYou Acan Aalso Autilize Athe Athree Adot Anotation Ato Acall Afunctions Awithin Aan Aarray Aof Aarguments.

let Anumbers A= A[5, A1, A7];

console.log(max(...numbers));

// A→ A7

Spread Athe Aarray Aout Ainto Aa Afunction Acall, Apass Athe Aelement Adifferent Aarguments, Alike Amax A(9, A...numbers, A2). AThe ASquare Abracket Aarray Anotation Aenables Athe Atriple-dot Aoperator Abring Aanother Aarray Ainto Aa Anew Aarray.

let Awords A= A["never", A"fully"];

console.log(["will", A...words, A"understand"]);

// A→ A["will", A"never", A"fully", A"understand"]

The AMath Aobjects

The AMath Aobject Ais Autilized Aas Avessel Ato Acollate Aa Alot Aof Asimilar Afunctionality. AIt Aproduces Aa Anamespace Ato Aenable Avalues Aa Afunctions Aand Afunctions Awithout Aglobal Abindings. AThis Ais Athe Aold Away Ato Awrite Athe Aconstant Avalue Aname Ain Aall Acaps.

function ArandomPointOnCircle(radius) A{

let Aangle A= AMath.random() A* A2 A* AMath.PI;

return A{x: Aradius A* AMath.cos(angle),

y: Aradius A* AMath.sin(angle)};

}

console.log(randomPointOnCircle(2));

// A→ A{x: A0.3667, Ay: A1.966}

The Amath Afunction Asends Aback Aa Anew Apseudo Arandom Anumber Abetween Azero Aand Aone Awhenever Ayou Acall Ait.

console.log(Math.random());

// A→ A0.36993729369714856

75

console.log(Math.random());

// A→ A0.727367032552138

console.log(Math.random());

// A→ A0.40180766698904335

When Ayou Aneed Aa Awhole Arandom Anumber Aand Anot Athe Afractional Aone, Ayou Acan Autilize Athe AMath.floor Aon Athe Aoutcome Aof Athe AMath.random.

console.log(Math.floor(Math.random() A* A10));

// A→ A2

The Arandom Anumber Ais Amultiplied Aby A10 Aand Aoutputs Aa Anumber Agreater Athan Aor Aequal Ato A0 Aand Abelow A10. ARemember Athe AMath.floor Arounds Adown, Athe Aoutput Awill Abe Aany Anumber Afrom A0 Athrough A9. AThe Amath Aobject Acontains Aseveral Afunctions Alike Athe AMath.ceil, Awhich Arounds Aup Ato Aa Awhole Anumber, Aand Athe AMath.round, Awhich Arounds Aup Ato Athe Anearest Awhole Anumber, Aand AMath.abs, Athis Afunction Atakes Athe Aentire Avalue Aof Aa Anumber.

Destructuring

Let’s Ause Athe Aphi Afunction Aa Alittle Abit.

function Aphi(chair) A{

return A(table[3] A* Achair[0] A- Atable[2] A* Achair[1]) A/

Math.sqrt((chair A[2] A+ Achair A[3]) A*

(table[0] A+ Achair A[1]) A*

(table[1] A+ Achair A[3]) A*

(table[0] A+ Achair A[2]));

}

One Aof Athe Afew Areasons Athis Afunction Ais Ahard Ato Aread Ais Abecause Athere Ais Aa Abinding Adirected Ato Athe Aarray, Abut Awe Awant Abindings Afor Athe Aelements Aof Athe Aarray, Athat Ais, Alet An00 A= Atable[0] Aand Aso Aon. AAlthough, Athere Ais Aa Abetter Away Ato Aget Athis Adone Ain AJavaScript.

function Aphi([n00, An01, An10, An11]) A{

return A(n11 A* An00 A- An10 A* An01) A/

Math.sqrt((n10 A+ An11) A* A(n00 A+ An01) A*

(n01 A+ An11) A* A(n00 A+ An10));

}

This Afunction Aalso Aperforms Abrilliantly Awith Athe Abindings Adeveloped Aby Athe Aleft, Avar, Aor Aconst. AIf Ayour Apreferred Abinding Avalue Ais Aan Aarray, Autilize Athe Asquare Abrackets Ato Acheck Afor Athe Avalue Aof Aits Abinding Acontents. AUse Athe Asame Aconcept Afor Aobjects, Autilize Athe Abraces Aand Anot Athe Asquare Abrackets.

let A{name} A= A{name: A"Faraji", Aage: A23};

console.log(name);

// A→ AFaraji

JSON

JSON Arepresents AJavaScript AObject ANotation Aand Ait Ais Autilized Aas Aa Acommunication Aformat Aand Adata Astorage Afor Athe Aweb. AJSON Ais Avery Asimilar Ato AJavaScript Ain Aits Awriting Astyle Aof Aarrays Aand Aobject, Aalthough Athere Aare Arestrictions. AIts Aproperty Anames Ashould Abe Aenclosed Awithin Adouble Aquotes, Ait Aallows Aonly Asimple Adata Aexpressions, Abinding Aetc. AJSON Ado Anot Aallow Acomments.

Here Ais Aa Asample Aof Aa Ajournal Aentry Arepresented Aas AJSON Adata:

{

"squirrel": Afalse,

"events": A["work", A"touched Atree", A"pizza", A"running"]

}

JavaScript Aconsists Aof Athe Afunctions AJSON.stringify Aand AJSON.parse Ato Atransform Adata Ato Aand Afrom Athis Aformat. AJSON.stringify Atakes Aa AJavaScript Avalue Aand Asends Aback Aa AJSON-encoded Astring Awhile AJSON.parse Atakes Aa Astring Aand Atransforms Ait Ato Aits Aencoded Avalue.

let Astring A= AJSON.stringify({squirrel: Afalse,

events: A["weekend"]});

console.log(string);

// A→ A{"squirrel":false,"events":["weekend"]}

console.log(JSON.parse(string).events);

// A→ A["weekend"]

Reversing Aan Aarray

Arrays Aconsist Aof Athe Areverse Amethod, Awhich Ais Aused Ato Achange Aan Aarray Aby Areversing Athe Aorder Athat Aits Aelements Adisplay.

Summary

We Acovered Athe Aobjects Aand Aarrays Ain Athis Achapter, Aand Athey Acreate Aways Ato Acategorize Avarious Avalues Ain Aa Asingle Avalue. AFancifully, Athis Aenables Ayou Ato Ainsert Aseveral Aassociated Aitems Ain Aa Abag Aand Amove Aabout Awith Athe Abag, Arather Athan Aenclosing Ayour Aarms Aaround Aevery Asingular Athing Aand Atrying Ato Akeep Athem Adifferently. AA Alot Aof Avalues Ain AJavaScript Acontain Aproperties, Athe Ainconsistency Abeing Aundefined Aand Anull. AYou Acan Aaccess Aproperties Ausing Athe Avalue.prop Aor Avalue["prop"]. AYou Acan Ause Anames Afor Aobjects Aproperties Aand Asave Aa Adefined Aset Aof Athem. AArrays, Aas Awell Acontain Adifferent Aamounts Aof Asimilar Afanciful Avalues Aand Autilize Athe Anumbers A(beginning Afrom A0) Aas Athe Aproperty’s Anames. AArrays Acontain Afew Asets Aof Aproperties, Awhich Aare Athe Alength Aand Aseveral Amethods. AMethods Aare Afunctions Athat Areside Awithin Aproperties Aand Abehave Aon Athe Avalue Athey Aare Aits Aproperty. AYou Acan Aloop Aacross Aarrays Athrough Aa Aunique Atype Aof Afor Aloop—for A(the Alet Aelement Aof Aan Aarray).

Exercise

Write Aa AJavaScript Afunction Ato Aobtain Athe Afirst Aitem Ain Aan Aarray. ASetting Aa Aparameter A'n' Awill Asend Aback Athe Afirst A'n' Aelements Aof Athe Aarray.

Data:

console.log(array_Clone([1, A2, A4, A0]));

console.log(array_Clone([1, A2, A[4, A0]]));

[1, A2, A4, A0]

[1, A2, A[4, A0]]

Solutions

Chapter 6: Higher-Order Functions

A Alarge Aprogram Atakes Atime Ato Adevelop Aand Aproduces Aa Alot Aof Aspace Afor Abugs Ato Ahide, Awhich Ain Aturn Amakes Athem Ahard Ato Afind. AHere Aare Aexamples Aof Atwo Alarge Aprograms:

The Afirst Ais Aself-contained, Aand Athe Astatement Ais Asix Alines Along.

let Atotal A= A0, Acount A= A1;

while A(count A<= A10) A{

total A+= Acount;

count A+= A1;

}

console.log(total);

The Asecond Adepends Aon Atwo Aexternal Afunctions, Aand Athe Astatement Ais Aone Aline Along.

console.log(sum(range(1, A10)));

Abstraction

When Ait Acomes Ato AJavaScript Aprogramming Alanguage, Avocabulary’s Ause Athe Aterm Aabstraction. AAbstraction Ais Aused Ato Ahide Adetails Aand Agives Athe Auser Athe Acapability Ato Atalk Aabout Aproblems Aon Aa Ahigher Alevel. ALet Aus Adifferentiate Atwo Arecipes Afor Apea Asoup. AFirst:

Per Aperson, Aplace A1 Acup Aof Adried Apeas Awithin Aa Acontainer. APut Aenough Awater Ato Acover Athe Apeas, Alet Ait Asoak Afor Aabout A12 Ahours. ARemove Ait Afrom Athe Awater Aand Aplace Ait Ain Aa Apot Aused Afor Acooking Awith Athe Aaddition Aof Awater Afour Acups Aof Awater A(4 Acups). ALet Ait Aboil Afor Aabout Atwo Ahours, Aper-person Ahold Ahalf Aof Aan Aonion, Aslice Ait Ausing Aa Aknife, Aand Apour Ait Ainto Athe Apeas, Alet Ait Aprepare Afor A10 Aminutes.

Then Athe Asecond Arecipe

Per Aperson: AHalf Aan Aonion, Aa Astalk Aof Acelery, A1 Acup Adried Asplit Apeas, Aand Aa Acarrot.

Dip Athe Apeas Ainto Athe Awater Afor Aabout A12 Ahours. ABoil Ait Afor Aabout A2 Ahours Ain Awater A(4 Acups), Aattach Aand Aslice Avegetables. ACook Ait Afor A10 Aminutes.

The Acomputer Aperforms Atasks Aone Aby Aone, Afrom Ablind Ato Ahigh-level Aconcepts.

Abstracting Arepetition

Plain Afunctions Aare Aused Ato Acreate Aabstractions. AIt Ais Ahabitual Afor Aa Aprogram Ato Arepeat Aa Aparticular Afunction Aa Aspecified Aamount Aof Atime. Ayou Acan Aachieve Athat Awith Aa Aloop Alike Athis:

83

for A(let Ai A= A0; Ai A< A10; Ai++) A{

console.log(i);

}

Here Awe Awrite Aa Afunction Athat Acalls Aconsole.log AN Atimes.

function ArepeatLog(n) A{

for A(let AI A= A0; AI A< An; AI++) A{

console.log(I);

}

}

If Ayou Awant Ato Aperform Aa Atask Adifferent Afrom Alogging Ain Anumbers, Ayou Acan Aroll Aaction Aas Aa Afunction Avalue.

function Arepeat(n, Aaction) A{

for A(let AI A= A0; AI A< An; AI++) A{

action(i);

}

}

repeat(3, Aconsole.log);

// A→ A0

// A→ A1

// A→ A2

Sometimes Ayou Ado Anot Aneed Ato Aroll Ain Aa Apredefined Afunction Ato Arepeat Ain Aa Aloop, Acreate Aa Afunction Avalue Aas Aan Aalternative:

let Alabels A= A[];

repeat(5, Ai A=> A{

labels.push(`Unit A${i A+ A1}`);

});

console.log(labels);

// A→ A["Unit A1", A"Unit A2", A"Unit A3", A"Unit A4", A"Unit A5"]

This Amethod Alayout Alooks Asimilar Ato Aa Aloop; Ait Adefines Athe Atype Aof Aloop Aand Athen Aproduce Aa Abody. AAlthough Athe Abody Ais Awritten Ain Afunction Aenclosed Ain Aparentheses Aof Athe Acall Ato Arepeat.

Higher-order Afunctions

Higher-order Afunctions Aare Afunctions Athat Awork Aon Aother Afunctions Awhether Aby Aarguments Aor Aby Asending Athem Aback. AThis Atype Aof Afunction Aenables Auser Ato Aabstract Aover Aactions. AFor Ainstance, Ayou Ahave Aa Afunction Athat Acan Aproduce Afunctions

function AgreaterThan(n) A{

return Am A=> Am A> An;

}

let AgreaterThan10 A= AgreaterThan(10);

console.log(greaterThan10(11));

// A→ Atrue

You Acan Aalso Ahave Afunctions Athat Acan Atransform Aother Afunctions.

function Anoisy(f) A{

return A(...args) A=> A{

console.log("calling Awith", Aargs);

let Aresult A= Af(...args);

console.log("called Awith", Aargs, A", Areturned", Aresult);

return Aresult;

};

}

noisy(Math.min)(3, A2, A1);

// A→ Acalling Awith A[3, A2, A1]

// A→ Acalled Awith A[3, A2, A1], Areturned A1

You Acan Aas Awell Awrite Afunctions Athat Aproduce Anew Aset Aof Acontrol Aflow.

function Aunless(test, Athen) A{

if A(!test) Athen();

}

85

repeat(3, An A=> A{

unless(n A% A2 A== A1, A() A=> A{

console.log(n, A"is Aeven");

});

});

// A→ A0 Ais Aeven

// A→ A2 Ais Aeven

This Amethod Ais Aa Abuilt-in Aarray Amethod, AforEach, Athat Aproduce Aa Aloop Asimilar Ato Athe Afor/of Aloop Aas Aa Ahigher-order Afunction.

["A", A"B"].forEach(l A=> Aconsole.log(l));

// A→ AA

// A→ AB

Filtering Aarrays

To Asearch Afor Athe Ascript Ain Aa Adata Aset, Ause Athe Afollowing Afunction. AThis Afunction Ahelps Ato Afilter Aout Aelement Athat Afailed Aa Atest Ain Aan Aarray.

function Afilter(array, Atest) A{

let Apassed A= A[];

for A(let Aelement Aof Aarray) A{

if A(test(element)) A{

passed.push(element);

}

}

return Apassed;

}

console.log(filter(SCRIPTS, Ascript A=> Ascript.living));

// A→ A[{name: A"Adlam", A…}, A…]

This Afunction Autilizes Athe Aargument Acalled Atest, Aa Afunction Avalue, Ato Acover Aa Agap Aduring Athe Acalculation. AIt Adetermines Awhich Aelement Ato Areceive.

Transforming Awith Amap

The Amap Amethod Achanges Aan Aarray Aby Asetting Aa Afunction Ato Aeach Aand Aevery Aof Aits Aelements Aand Acreating Aa Anew Aarray Afrom Athe Areturned Avalues. AThe Anew Aarray Aconsists Aof Athe Asame Alength Awith Athe Ainput Aarray Abut Awill Amap Aout Aits Acontent Ato Aa Arenewed Afor Aby Athe Afunction.

function Amap(array, Atransform) A{

let Amapped A= A[];

for A(let Aelement Aof Aarray) A{

mapped.push(transform(element));

}

return Amapped;

}

let ArtlScripts A= ASCRIPTS.filter(s A=> As.direction A== A"rtl");

console.log(map(rtlScripts, As A=> As.name));

// A→ A["Adlam", A"Arabic", A"Imperial AAramaic", A…]

Like AforEach Aand Afilter.

Summarizing Awith Areduce

When Ayou Aadd Aup Anumbers, Abegin Awith Azero Aand Aadd Athe Aforeach Aelement Ato Athe Asum. AThe Aparameter Ato Areduce Aare Amap Afunction Acombination Aand Abegin Aa Avalue. AThis Afunction Ais Amuch Aeasier Ato Aunderstand Athan Athe Afilter Aand Amap. AIt Ais Abelow:

function Areduce(array, Acombine, Abegin) A{

let Acurrent A= Abegin;

for A(let Aitems Aof Aarrays) A{

existing A= Acombine(existing, Aelement);

}

return Aexisting;

}

console.log(reduce([0,1, A2, A3, A4], A(a, Ab) A=> Aa A+ Ab, A0));

// A→ A10

This Afunction Ais Asimilar Ato Athe Astandard Aarray Amethod Areduce Aand Aattaches Amore Acomfort.

console.log([1, A2, A3, A4].reduce((a, Ab) A=> Aa A+ Ab));

// A→ A10

If Ayou Awant Ato Autilize Areduce Ato Asearch Afor Athe Ascript Awith Athe Amore Acharacters, Awrite Ait Alike Athis:

function AcharacterCount(script) A{

return Ascript.ranges.reduce((count, A[from, Ato]) A=> A{

return Acount A+ A(to A- Afrom);

}, A0);

}

console.log(SCRIPTS.reduce((a, Ab) A=> A{

return AcharacterCount(a) A< AcharacterCount(b)? Ab: Aa;

}));

// A→ A{name: A"Han", A…}

Composability

Take Asome Atime Ato Athink Aabout Ahow Along Aour Alist Aof Acode Awould Ahave Abeen Awithout Athe Ahigher-order Afunctions.

let Abiggest A= Anull;

for A(let Ascript Aof ASCRIPTS) A{

if A(biggest A== Anull A||

characterCount(biggest) A< AcharacterCount(script)) A{

biggest A= Ascript;

}

}

console.log(biggest);

// A→ A{name: A"Han", A…}

You Acan Ause Athe Ahigh-order Afunctions Awhen Ayou Awant Ato Acompose Aoperations. AFor Ainstance, Ahere Ais Aa Aline Aof Acode Athat Asearches Afor Athe Aaverage Ayear Afor Aliving Aand Adead Ain Ahumans’ Ascripts Ain Athe Adata Aset.

function Aaverage(array) A{

return Aarray.reduce((a, Ab) A=> Aa A+ Ab) A/ Aarray.length;

}

console.log(Math.round(average(

SCRIPTS.filter(s A=> As.living).map(s A=> As.year))));

// A→ A1165

console.log(Math.round(average(

SCRIPTS.filter(s A=> A!s.living).map(s A=> As.year))));

// A→ A204

The Ablock Aof Acode Adisplays Athat Athe Adeath Ascript Ais Aolder Athan Athe Aliving Aones.

Let’s Abegin Awith Athe Aentire Ascript, Afilter Aout Athe Adead A(or Aliving), Aeradicate Atheir Ayears, Aaverage Athem Aand Acomplete Athe Aresult. AYou Acan Aas Awell Awrite Athese Acalculations Aas Aa Abig Aloop:

let Atotal A= A0, Acount A= A0;

for A(let Ascript Aof ASCRIPTS) A{

if A(script.living) A{

total A+= Ascript.year;

count A+= A1;

}

}

console.log(Math.round(total A/ Acount));

// A→ A1165

Our Atwo Aexamples Aare Anot Aidentical, Athe Afirst Acreates Anew Aarrays Awhen Aadministering Athe Amap Aand Afilter Awhile Athe Asecond Acalculate Anumbers Aonly.

Strings Aand Acharacter Acodes

One Aof Athe Asignificant Ause Aof Adata Aset Ais Ato Afind Aout Awhat Ascript Aa Ablock Aof Atext Ais Ausing. ABelow Ais Aa Aprogram Athat Aperforms Athat Atask.

Every Ascript Acontains Aan Aarray Aof Acharacter Acode Aranges Arelated Awith Ait. ASo, Aif Ayou Aare Agiven Aa Acharacter Acode, Autilize Athis Afunction Ato Asearch Afor Athe Aequivalent Ascript A(if Aavailable):

function AcharacterScript(code) A{

for A(let Ascript Aof ASCRIPTS) A{

if A(script.ranges.some(([from, Ato]) A=> A{

return Acode A>= Afrom A&& Acode A< Ato;

})) A{

return Ascript;

}

}

return Anull;

}

console.log(characterScript(121));

// A→ A{name: A"Latin", A…}

Another Ahigh-order Afunction Ais Athe Asame Amethod. AThis Amethod Agets Aa Atest Afunction Aand Adetermine Aif Athat Afunction Asends Aback Atrue Afor Aany Acomponent Ain Athe Aarray.

There Aare Asome Aoperations Aon AJavaScript Astrings Alike Asecuring Atheir Alength Ausing Athe Alength Aproperty Aand Aevaluating Atheir Acontents Athrough Athe Asquare Abrackets.

// ATwo Aemoji Acharacters, Ahorse Aand Ashoe

let AhorseShoe A= A"🐴👟";

console.log(horseShoe.length);

// A→ A4

console.log(horseShoe[0]);

// A→ A(Invalid Ahalf-character)

console.log(horseShoe.charCodeAt(0));

// A→ A55357 A(Code Aof Athe Ahalf-character)

console.log(horseShoe.codePointAt(0));

// A→ A128052 A(Actual Acode Afor Ahorse Aemoji)

JavaScript’s AcharCodeAt Amethod Aoffers Aa Afull AUnicode Acharacter. AThis Amethod Ais Aused Ato Atake Acharacters Afrom Aa Astring. AAlthough Athe Aargument Asent Ato AcodePointAt Aremains Aan Aindex Ainto Athe Asuccession Aof Acode Aunits. AIf Ayou Ause Athe AcodePointAt Ato Aloop Aacross Aa Astring, Ait Aproduces Areal Acharacters Aand Anot Acode Aunits.

let AroseDragon A= A"🌹🐉";

for A(let Achar Aof AroseDragon) A{

console.log(char);

}

// A→ A🌹

// A→ A🐉

Recognizing Atext

You Ahave Athe Acharacter AScript Afunction Aand Aa Away Ato Aloop Aacross Acharacters Acorrectly, Anow Acalculate Athe Acharacters Aeach Ascript Aowns. AThe Abelow Acounting Aabstraction Ais Aused Ahere:

function AcountBy(items, AgroupName) A{

let Acounts A= A[];

for A(let Aitem Aof Aitems) A{

let Aname A= AgroupName(item);

let Aknown A= Acounts.findIndex(c A=> Ac.number A== Aname);

if A(known A== A-1) A{

counts.push({nunber, Acount: A0});

} Aelse A{

counts[know].count++;

}

}

return Acounts;

}

console.log(countBy([0,1, A2, A3, A4, A5], An A=> An A> A2));

// A→ A[{number: Afalse, Acount: A2}, A{number: Atrue, Acount: A3}]

The AcountBy Afunction Aanticipates Aa Acollection A(a Agroup Aof Anumbers, Aelement Aor Aanything Athat Ayou Acan Aloop Aover Awith Afor/of) Aand Aa Afunction Athat Acalculates Aa Agroup Aname Afor Aa Aspecified Aelement. AIt Asends Aback Aa Alist Aof Aobjects. AEach Aof Athe Aobjects Anames Aa Agroup Aand Adetermines Athe Anumber Aof Aelements Acontained Ain Athe Agroup.

The Amethod AfindIndex Ais Asimilar Ato AindexOf. AThis Amethod Ais Aused Ato Asearch Afor Athe Afirst Avalue Afor Awhich Athe Astated Afunction Asends Aback Atrue Aand Areturns A-1 Awhen Azero Aelements Ais Afound. AYou Acan Ause Athe AcountBy Ato Adetermine Awhich Ascript Ais Autilized Ain Aa Ablock Aof Atext.

function AtextScripts(text) A{

let Ascripts A= AcountBy(text, Achar A=> A{

let Ascript A= AcharacterScript(char.codePointAt(0));

return Ascript? Ascript.name A: A"none";

}).filter(({name}) A=> Aname A!= A"none");

let Atotal A= Ascripts.reduce((n, A{count}) A=> An A+ Acount, A0);

if A(total A== A0) Areturn A"No Ascripts Afound";

return Ascripts.map(({name, Acount}) A=> A{

return A`${Math.round(count A* A100 A/ Atotal)}% A${name}`;

}).join(", A");

}

console.log(textScripts('英国的狗说"woof", A俄罗斯的狗说"тяв"'));

// A→ A61% AHan, A22% ALatin, A17% ACyrillic

The Afunction Acalculates Athe Acharacters Aby Aname Athrough Athe Ause Aof AcharacterScript Ato Aattach Aa Aname Aand Areturning Aback Ato Athe Astring A"none" Afor Acharacters Awithout Aany Ascript. AIf Ayou Awant Ato Acalculate Apercentages, Ayou Aneed Ato Adetermine Athe Atotal Aamount Aof Acharacters Abelonging Ato Aa Ascript Athat Athe Areduce Amethod Acan Areduce. AIf Ait Afinds Azero Acharacters, Athe Afunction Asends Aback Athe A"none" Astring.

Summary

Having Athe Aability Ato Asend Afunction Avalues Ato Aseveral Afunctions Ais Aan Aessential Aaspect Aof AJavaScript. AIt Aenables Awriting Afunctions Athat Aimitate Acomputations Awith A“gaps” Abetween Athem. AThe Acode Athat Adeclares Athese Afunctions Acan Acontain Athe Agaps Aby Agiving Afunction Avalues. AArrays Aprovide Aseveral Aimportant Ahigher-order Amethods. AUse AforEach Ato Aloop Aacross Aelements Awithin Aan Aarray. AUse Athe Afilter Amethod Ato Asend Aback Aa Anew Aarray Athat Ahas Aelements Athat Aconvey Athe Apredicate Afunction. AChanging Aan Aarray Aby Asetting Aeach Aitem Athrough Aa Afunction Ausing Athe Amap. AUse Areduce Ato Amerge Aevery Acomponent Aof Aan Aarray Ato Aan Aindividual Avalue.

Exercises

Illustrate Aa AJavaScript Afunction Athat Atakes Aan Aarray Aof Anumbers Asaved Aand Asearch Afor Athe Asecond-lowest Aand Asecond Ahighest Anumbers.

Solution

Chapter 7: The Secret Life
of Objects

When Ait Acomes Ato APrograming Alanguages, Athere Ais Aa Aset Atechnique Athat Autilizes Aobjects Aas Aa Afundamental Aidea Aof Aprogram Aorganization, Aand Athey Aare Acalled Athe Aobject-oriented Aprogramming. AIts Aconcept Awill Abe Aexplained Afurther Ain Athis Achapter.

Encapsulation

The Aprimary Aimportance Aof Aobject-oriented Aprogramming Ais Ato Abreak Aprograms Ainto Alittle Apieces Aand Amakes Asure Aeach Apiece Amanages Aits Asection. ASeveral Afragments Aof Asimilar Aprograms Acommunicate Awith Aeach Aother Ausing Ainterfaces, Aa Arestricted Aset Aof Afunctions Aor Abinding Athat Aproduce Aessential Afunctionality Aon Aa Ahigher Alevel, Ahiding Athe Aspecific Aexecution. AIllustrate Athis Atype Aof Aprogram Apieces Athrough Aobjects, Aand Atheir Alayout Acontains Aa Aparticular Aset Aof Aproperties Aand Amethods. AProperties Awithin Athe Alayout Aare Apublic Awhile Athe Aouter Acode Ais Aprivate. ADefine Athe Aaccessible Alayout Ain Acomments Aor Adocumentation. AIt Aregularly Auses Athe Aunderscore A(_) Acharacter Aat Athe Abeginning Aof Aproperty Anames Ato Asignify Aprivate Aproperties. AMeanwhile, Adiving Alayouts Afrom Aexecution Ais Acalled Aencapsulation.

Methods

Methods Aare Aproperties Athat Agrasp Afunction Avalues.

let Arabbit A= A{};

rabbit.speak A= Afunction(line) A{

console.log(`The Arabbit Asays A'${line}'`);

};

rabbit.speak("I'm Aalive.");

// A→ AThe Arabbit Asays A'I'm Aalive.'

When Ayou Acall Aa Afunction Aas Aa Amethod, Athe Abinding Acalls Ait Ain Aits Abody Aand Adirect Athe Aobject Ait Awas Acalled Aon.

function Aspeak(line) A{

console.log(`The A${this.type} Arabbit Asays A'${line}'`);

}

let AwhiteRabbit A= A{type: A"white", Aspeak};

let AhungryRabbit A= A{type: A"hungry", Aspeak};

whiteRabbit.speak("Oh Amy Awhiskers," A+ A"how Alate Ait's Agetting!");

// A→ AThe Awhite Arabbit Asays A'Oh Amy Awhiskers, Ahow

// Alate Ait's Agetting!'

HungryRabbit.speak("I Acould Ause Aa Acarrot Aright Anow.");

// A→ AThe Ahungry Arabbit Asays A'I Acould Ause Aa Acarrot Aright Anow.'

Arrow Afunctions Aare Ado Anot Abind Atheir Aown. AYou Acan Awrite Athe Afollowing Acode:

function Anormal() A{

console.log(this.coords.map(n A=> An A/ Athis.length));

}

normal.call({coords: A[0, A2, A3], Alength: A5});

// A→ A[0, A0.4, A0.6]

Prototypes

Keep Aan Aeye Aout Aon Athis.

let Aempty A= A{};

console.log(empty.toString);

// A→ Afunction AtoString()…{}

console.log(empty.toString());

// A→ A[object AObject]

A Aproperty Ais Apulled Aout Aof Aan Aempty Aobject. AA Alot Aof AJavaScript Aobjects Aconsists Aof Aa Aprototype. AThis Ais Aan Aobject Aused Aas Aan Aalternative Asource Aof Aproperties. ATherefore, Athe Aprototype Aof Athat Aempty Aobject Ais Athe Ainherited Aprototype, Athe AObject.prototype.

console.log(Object.getPrototypeOf({}) A==

Object.prototype);

// A→ Atrue

console.log(Object.getPrototypeOf(Object.prototype));

// A→ Anull

Object.getPrototypeOf Asends Aback Athe Aprototype Aof Aan Aobject. AThis Aprototype Aproduces Asome Amethod Athat Adisplays Ain Aevery Aobject Alike AtoString Athat Atransforms Aan Aobject Ato Aa Astring Aexecution.

A Alot Aof Aobjects Ado Anot Acontain AObject.prototype Aas Atheir Aprototype Abut Ause Aanother Aobject Athat Aproduces Aa Aseparate Aset Aof Adefault Aproperties;

Functions Aacquires Afrom AFunction.prototype, Aand Aarrays Aacquires Afrom AArray

.prototype.

console.log(Object.getPrototypeOf(Math.max) A==

Function.prototype);

// A→ Atrue

console.log(Object.getPrototypeOf([]) A==

Array.prototype);

// A→ Atrue

This Atype Aof Aprototype Aobject Acontains Aa Aprototype, Athe AObject.prototype, Aso Athat Ait Acan Acreate Amethods Asuch Aas AtoString Aindirectly. AUse Athe AObject.create Ato Abuild Aan Aobject Awith Aa Aparticular Aprototype.

let AprotoRabbit A= A{

speak(line) A{

console.log(`The A${this.type} Arabbit Asays A'${line}'`);

}

};

let AkillerRabbit A= AObject.create(protoRabbit);

killerRabbit.type A= A"killer";

killerRabbit.speak("SKREEEE!");

// A→ AThe Akiller Arabbit Asays A'SKREEEE!

They Aspeak(line) Aproperty Ain Aan Aobject Aexpression Aproduces Aa Aproperty Acalled Aspeak Aand Aset Aa Afunction Aas Aits Avalue. AIt Ais Aa Ashorthand Away Aof Adescribing Aa Amethod.

The A“proto” Arabbit Ais Aa Acontainer Afor Aall Aproperties.

Classes

JavaScript’s Aprototype Asystem Acan Abe Adescribed Aas Asubsidiary Aon Aan Aobject-oriented Amethod Acalled Aclasses. AA Aclass Adescribes Aan Aobject Atype's Ashape, Aits Aproperties Aand Amethods. APrototypes Aare Aused Ato Adescribe Aproperties Awhereby Aevery Ainstance Ashare Asimilar Avalues Asuch Aas Amethods. AIf Ayou Awant Ato Abuild Aan Ainstance Aof Aa Aset Aclass, Acreate Aan Aobject Athat Areceives Afrom Athe Anormal APrototype. AMake Asure Ait Acontains Aproperties Athat Ashould Abe Aincluded Ain Athe Ainstance Aof Athis Aclass. ABelow Ais Athe Aconstructor Afunction.

function AmakeRabbit(type) A{

let Arabbit A= AObject.create(protoRabbit);

rabbit.type A= Atype;

return Arabbit;

}

JavaScript Aoffers Aa Away Ato Amake Adescribing Athis Afunction Aeffortlessly. ASet Athe Akeyword Aat Athe Afront Aof Aa Afunction Acall. AThe Aprototype Aobject Autilized Aduring Athe Aconstruction Aof Aobjects Ais Aattained Aby Afetching Athe Aprototype Aproperty Aof Athe Aconstructor Afunction.

function ARabbit(type) A{

this.type A= Atype;

}

Rabbit.prototype.speak A= Afunction(line) A{

console.log(`The A${this.type} Arabbit Asays A'${line}'`);

};

let AweirdRabbit A= Anew ARabbit("weird");

Function.prototype Ais Athe Aprototype Aof Aa Aconstructor. AIts Aprototype Aproperty Agrasps Athe Aprototype Autilized Afor Ainstances Abuilt Athrough Ait.

console.log(Object.getPrototypeOf(Rabbit) A==

Function.prototype);

// A→ Atrue

console.log(Object.getPrototypeOf(weirdRabbit) A==

Rabbit.prototype);

// A→ Atrue

Class Anotation

JavaScript Aclasses Aare Aconstructor Afunctions Awith Aa Aprototype Aproperty. ABelow Ais Aa Asample:

class ARabbit A{

constructor(type) A{

this.type A= Atype;

}

speak(line) A{

console.log(`The A${this.type} Arabbit Asays A'${line}'`);

}

}

let AkillerRabbit A= Anew ARabbit("killer");

let AblackRabbit A= Anew ARabbit("black");

The Aclass Akeyword Abegins Awith Aa Aclass Adeclaration, Awhich Aenables Ayou Ato Adescribe Aa Aconstructor Aand Aa Aset Aof Amethods Ain Aa Aparticular Aplace. AClass Adeclarations Aenables Amethods, Aproperties Athat Agrasp Afunctions Ato Abe Aincluded Ain Athe Aprototype. AWhen Ayou Ause Aan Aexpression, Ait Adoes Anot Adescribe Aa Abinding Abur Aprovides Athe Aconstructor Aas Aa Avalue. AYou Acan Aexclude Athe Aclass Aname Ain Aan Aexpression.

let Aobject A= Anew Aclass A{getWord() A{ Areturn A"hello"; A} A};

console.log(object.getWord());

// A→ Ahello

Overriding Aderived Aproperties

When Aa Aproperty Ais Aadded Ato Aan Aobject, Aeither Aavailable Ain Athe Aprototype Aor Anot, Athe Aproperty Aadds Ato Athe Aobject. AIf Athere Awas Aan Aassigned Aproperty Awith Asimilar Anames Ain Athe Aprototype, Ait Adoes Anot Ainfluence Athe Aobject.

Rabbit.prototype.teeth A= A"small";

console.log(killerRabbit.teeth);

// A→ Asmall

killerRabbit.teeth A= A"long, Asharp, Aand Abloody";

console.log(killerRabbit.teeth);

// A→ Along, Asharp, Aand Abloody

console.log(blackRabbit.teeth);

// A→ Asmall

console.log(Rabbit.prototype.teeth);

// A→ Asmall

Overriding Aproperties Ais Aused Ato Abestow Aa Astandard Afunction Aand Aarray Aprototypes Aa Aseparate AtoString Amethod.

console.log(Array.prototype.toString A==

Object.prototype.toString);

// A→ Afalse

console.log([1, A3].toString());

// A→ A1,3

Calling AtoString Aon Aan Aarray Abestows Aa Aresult Athat Ais Alikened Ato Acalling. Ajoin(",") Aon Ait. AIt Aplaces Aa Acomma Abetween Athe Avalues Acontained Ain Athe Aarray. AIf Ayou Acall AObject.prototype.toString Ato Aan Aarray, Ait Aprovides Aa Aseparate Astring.

console.log(Object.prototype.toString.call([1, A3]));

// A→ A[object AArray]

Maps

A Amap Ais Aa Adata Alayout Athat Aconnect Avalues Awith Aother Avalues. AIf Ayou Awant Ato Amap Anames Ato Aages, Awrite Ayour Acode Alike Athis:

let Aages A= A{

Boris: A39,

Liang: A22,

Júlia: A62

};

console.log(`Julia Ais A${ages["Julia"]}`);

// A→ AJulia Ais A62

console.log("Is AJack's Aage Aknown?", A"Jack" Ain Aages);

// A→ AIs AJack's Aage Aknown? Afalse

console.log("Is AtoString's Aage Aknown?", A"toString" Ain Aages);

// A→ AIs AtoString's Aage Aknown? Atrue

Object Aproperty Anames Ashould Abe Ain Astrings. AIf Ayou Awant Aa Amap Athat Athe Akeys Acannot Abe Atransformed Ato Astrings, Ado Anot Ause Aobject Aas Aa Amap. AJavaScript Acontains Aa Aclass Acalled Amap. AIt Asaves Amapping Aand Aenables Adifferent Atypes Aof Akeys.

let Aages A= Anew AMap();

ages.set("Boris", A39);

ages.set("Liang", A22);

ages.set("Júlia", A62);

console.log(`Júlia Ais A${ages.get("Júlia")}`);

// A→ AJúlia Ais A62

console.log("Is AJack's Aage Aknown?", Aages.has("Jack"));

// A→ AIs AJack's Aage Aknown? Afalse

console.log(ages.has("toString"));

// A→ Afalse

The Amethods Aget, Aset, Aand Ahas Aare Abodies Aof Athe Alayout Aof Athe Amap Aobject. AThe AObject.keys Asends Aback Aan Aobject’s Aown Akeys Aonly. AYou Acan Ause Athe AhasOwnProperty Amethod Aas Aan Aoption.

console.log({x: A1}.hasOwnProperty("x"));

// A→ Atrue

console.log({x: A1}.hasOwnProperty("toString"));

// A→ Afalse

Polymorphism

When Aa Astring Afunction Ais Acalled Aon Aan Aobject, Athe AtoString Amethod Ais Acalled Aon Athat Aobject Ain Aorder Ato Abuild Aa Asignificant Astring Afrom Ait. AYou Acan Adefine Ayour Aown Aversion Aof AtoString Aso Athat Athey Acan Abuild Aa Astring Athat Aconsists Aof Amore Aimportant Adata Amore Athan Athe A"[object AObject]". ABelow Ais Aan Aillustration:

Rabbit.prototype.toString A= Afunction() A{

return A`a A${this.type} Arabbit`;

};

console.log(String(blackRabbit));

// A→ Aa Ablack Arabbit

When Aa Aline Aof Acode Ais Awritten Ato Afunction Awith Aobjects Athat Ahave Aa Aspecific Alayout Ais Acalled Apolymorphism. APolymorphic Acode Acan Afunction Aproperly Awith Avalues Aof Aseveral Ashapes.

Symbols

Symbols Aare Aunique Avalues Abuilt Awith Athe ASymbol Afunction Awhich Acannot Abe Abuilt Atwice.

let Asym A= ASymbol("name");

console.log(sym A== ASymbol("name"));

// A→ Afalse

Rabbit.prototype[sym] A= A55;

console.log(blackRabbit[sym]);

// A→ A55

The Astring Apassed Ato Athe Asymbol Ais Aattached Awhen Ayou Atransform Ait Ato Aa Astring. AThey Aare Adistinctive Aand Afunctions Aas Aproperty Anames.

const AtoStringSymbol A= ASymbol("toString");

Array.prototype[toStringSymbol] A= Afunction() A{

return A`${this.length} Acm Aof Ablue Ayarn`;

};

console.log([1, A2].toString());

// A→ A1,2

console.log([1, A2][toStringSymbol]());

// A→ A2 Acm Aof Ablue Ayarn

You Acan Aattach Athe Asymbol Aproperties Ain Aobject Aclasses Aand Aexpressions Athrough Athe Ause Aof Asquare Abrackets Asurrounding Athe Aproperty Aname. ABelow Awe Arefer Ato Aa Abinding Astoring Athe Asymbol.

let AstringObject A= A{

[toStringSymbol]() A{ Areturn A"a Ajute Arope"; A}

};

console.log(stringObject[toStringSymbol]());

// A→ Aa Ajute Aropes

The Aiterator Ainterfaces

The Astated Aobject Ato Aa Afor/of Aloop Ais Aiterable. AThis Ameans Athat Ait Aconsists Aof Aa Anamed Amethod Awith Athe ASymbol.iterator Asymbol Awhen Athe Aproperty Ais Acalled. AThe Amethod Asends Aback Aan Aobject Athat Aproduces Aa Asecond Alayout. AIt Acontains Aa Anext Amethod Athat Asends Aback Athe Afollowing Aresult. AThe Aresult Ais Aan Aobject Awith Aa Avalue Aproperty Athat Aproduces Athe Anext Avalue, ASymbol.iterator Acan Abe Aadded Ato Aseveral Aobjects. ACheckout Athis Alayout:

let AokIterator A= A"OK"[Symbol.iterator]();

console.log(okIterator.next());

// A→ A{value: A"O", Adone: Afalse}

console.log(okIterator.next());

// A→ A{value: A"K", Adone: Afalse}

console.log(okIterator.next());

// A→ A{value: Aundefined, Adone: Atrue}

Let’s Aimplement Aan Aiterable Adata Astructure. AWe’ll Abuild Aa Amatrix Aclass, Aacting

as Aa Atwo-dimensional Aarray Aclass AMatrix A{

constructor(width, Aheight, Aelement A= A(x, Ay) A=> Aundefined) A{

this.width A= Awidth;

this.height A= Aheight;

this.content A= A[];

for A(let Ay A= A0; Ay A< Aheight; Ay++) A{

for A(let Ax A= A0; Ax A< Awidth; Ax++) A{

this.content[y A* Awidth A+ Ax] A= Aelement(x, Ay);

}

}

}

get(x, Ay) A{

return Athis.content[y A* Athis.width A+ Ax];

}

set(x, Ay, Avalue) A{

this.content[y A* Athis.width A+ Ax] A= Avalue;

}

}

The Acontent Aof Athe Aclass Ais Asaved Ain Aan Aindividual Aarray Aof Awidth A× Aheight Aelements. AThese Aelements Aare Asaved Arow Aafter Arow. AThe Aconstructor Afunction Agets Aa Awidth, Aheight, Aand Aan Aadditional Aelement Afunction, Awhich Ais Aused Ato Aset Athe Ainitial Avalues. AUse Athe Aget Amethod Aand Aset Amethod Ato Arecover Aand Aupdate Aelements Awithin Athe Amatrix. ABelow Ais Athe Alayout Aof Aobjects Awith Ax, Ay, Aand Avalue Aproperties.

class AMatrixIterator A{

constructor(matrix) A{

this.x A= A0;

this.y A= A0;

this.matrix A= Amatrix;

}

next() A{

if A(this.y A== Athis.matrix.height) Areturn A{done: Atrue};

let Avalue A= A{x: Athis.x,

y: Athis.y,

value: Athis.matrix.get(this.x, Athis.y)};

this.x++;

if A(this.x A== Athis.matrix.width) A{

this.x A= A0;

this.y++;

}

return A{value, Adone: Afalse};

}

}

Below Ais Aan Aillustration Aof Aan Aiterable AMatrix Aclass:

Matrix.prototype[Symbol.iterator] A= Afunction() A{

return Anew AMatrixIterator(this);

};

We Acan Anow Aloop Aover Aa Amatrix Awith Afor/of.

let Amatrix A= Anew AMatrix(2, A2, A(x, Ay) A=> A`value A${x},${y}`);

for A(let A{x, Ay, Avalue} Aof Amatrix) A{

console.log(x, Ay, Avalue);

}

// A→ A0 A0 Avalue A0,0

// A→ A1 A0 Avalue A1,0

// A→ A0 A1 Avalue A0,1

// A→ A1 A1 Avalue A1,1

Statics, Agetters, Aand Asetters

Layouts Aconsists Aof Amethods, Abut Ayou Acan Aalso Aattach Aproperties Athat Astores Avalues Awith Ano Afunction Alike Aa AMap Aobject Acontaining Aa Asize Aproperty Athat Adetermines Ahow Amany Akeys Aare Asaved Ain Athem. AAn Aassessed Aproperty Acan Ahide Aa Amethod Acall. AThose Amethods Aare Acalled Agetters, Aand Ayou Acan Adescribe Athem Aby Awriting A"get" Aat Athe Abeginning Aof Athe Amethod Aname Ain Aa Aclass Adeclaration Aor Aan Aobject Aexpression.

let AvaryingSize A= A{

get Asize() A{

return AMath.floor(Math.random() A* A100);

}

};

console.log(varyingSize.size);

// A→ A73

console.log(varyingSize.size);

// A→ A49

When Ayou Awant Ato Ause Aan Aobject’s Asize Aproperty, Ayou Acall Athe Aassociated Amethod. AYou Acan Aperform Aa Asimilar Atask Awhen Ayou Aa Aproperty Ausing Aa Asetter.

class ATemperature A{

constructor(celsius) A{

this.celsius A= Acelsius;

}

get Afahrenheit() A{

return Athis.celsius A* A1.8 A+ A32;

}

set Afahrenheit(value) A{

this.celsius A= A(value A- A32) A/ A1.8;

}

static AfromFahrenheit(value) A{

return Anew ATemperature((value A- A32) A/ A1.8);

}

}

let Atemp A= Anew ATemperature(22);

console.log(temp.fahrenheit);

// A→ A71.6

temp.fahrenheit A= A86;

console.log(temp.celsius);

// A→ A30

The ATemperature Aclass Aenable Ayou Ato Aread Aand Awrite Athe Atemperature Ain Adegrees ACelsius Aor Adegrees AFahrenheit, Abut Ait Asaves Aonly ACelsius Aand Atransform Ato Aand Afrom ACelsius Ain Athe AFahrenheit Agetter Aand Asetter. AWithin Aa Aclass Adeclaration, Amethods Athat Aare Astatic Awritten Abefore Atheir Anames Aare Asaved Aon Athe Aconstructor. ASo, Ayou Acan Awrite ATemperature.fromFahrenheit(100) Ato Abuild Aa Atemperature Athrough Adegrees AFahrenheit.

Inheritance

Some Amatrices Aare Asymmetric. AWhen Ayou Areflect Aa Asymmetric Amatrix Athrough Aits Atop-left-to-bottom-right Adiagonal, Ait Adoes Anot Achange. AThe Avalue Aset Aat Ax,y Aremains Athe Asame Aas Athe Ay,x. AUse Athe AJavaScript’s Aprototype Asystem Ato Abuild Aa Anew Aclass, Athe Aprototype Afor Athe Anew Aclass Ais Aacquired Afrom Athe Aold Aprototype Abut Asets Aa Anew Adefinition Afor Athe Amethod. AThis Ais Acalled Ainheritance Ain Aobject-oriented Aprogramming Aterms. ABelow Ais Aan Aillustration:

class ASymmetricMatrix Aextends AMatrix A{

constructor(size, Aelement A= A(x, Ay) A=> Aundefined) A{

super(size, Asize, A(x, Ay) A=> A{

if A(x A< Ay) Areturn Aelement(y, Ax);

else Areturn Aelement(x, Ay);

});

}

set(x, Ay, Avalue) A{

super.set(x, Ay, Avalue);

if A(x A!= Ay) A{

super.set(y, Ax, Avalue);

}

}

}

let Amatrix A= Anew ASymmetricMatrix(5, A(x, Ay) A=> A`${x},${y}`);

console.log(matrix.get(2, A3));

// A→ A3,2

The Ainstanceof Aoperator

It Ais Aimportant Ato Aknow Aif Aan Aobject Awas Agotten Afrom Aa Aparticular Ainstanceof.

console.log(

new ASymmetricMatrix(2) Ainstanceof ASymmetricMatrix);

// A→ Atrue

console.log(new ASymmetricMatrix(2) Ainstanceof AMatrix);

// A→ Atrue

console.log(new AMatrix(2, A2) Ainstanceof ASymmetricMatrix);

// A→ Afalse

console.log([1] Ainstanceof AArray);

// A→ Atrue

The Aoperator Awill Ascan Athrough Athe Atypes Athat Awere Ainherited. ATherefore, Aa ASymmetricMatrix Ais Aan Ainstance Aof AMatrix. AYou Acan Aalso Aapply Athis Amethod Ato Astandard Aconstructors Alike AArray.

Summary

In Athis Achapter, Awe Arealize Athat Aobjects Acan Aperform Amore Athan Aholding Atheir Aproperties. AThey Aconsist Aof Aprototypes Athat Aare Aobjects Aas Awell. AThey Abehave Alike Athey Acontain Aproperties Athat Athey Ado Anot Aprovide Aas Along Aas Athe Aprototype Ahas Athat Aproperty. ASimple Aobjects Ause Athe AObject. APrototype Ato Arepresent Atheir Aprototype. AWe Atalked Aabout AConstructors Atoo, Aand Athey Aare Afunctions Athat Atheir Anames Aoften Abegin Awith Aa Acapital Aletter, Aand Aused Awith Athe Anew Aoperator Ato Abuild Anew Aobjects. AThe Anew Aobject’s Aprototype Awould Abe Athe Aobject Awithin Athe Aprototype Aproperty Aof Athe Aconstructor. AA Aclass Anotation Aoffers Aa Away Ato Adescribe Aa Aconstructor Aand Aits Aprototype. AWe Aalso Atouched Athe AGetters, Asetters, Aand Astatics Aand Athe Ainstanceof Aoperator.

Exercise

Write Aa AJavaScript Aprogram Ato Acreate Aan Aarray, Athrough Aan Aiterator Afunction Aand Aa Aprimary Aseed Avalue.

Solution

Chapter 8: A Robot

In Athis Achapter, Athere Awill Abe Awork Aon Aa Arobot Aprogram, Aa Ashort Aprogram Athat Aexecutes Aa Atask Ain Aa Avirtual Aworld. AWe Awill Abe Ausing Aa Amail Adelivery Arobot Areceiving Aand Adelivering Aparcels.

Meadow Afield

The AMeadow Afield Avillage Ais Aa Asmall Aone Aconsisting Aof A14 Aroads Aand A11 Aplaces. ABelow Ais Aan Aillustration Awith Aan Aarray Aof Aroads:

const Aroads A= A[

"Alice's AHouse-Bob's AHouse", A"Alice's AHouse-Cabin",

"Alice's AHouse-Post AOffice", A"Bob's AHouse-Town AHall",

"Daria's AHouse-Ernie's AHouse", A"Daria's AHouse-Town AHall",

"Ernie's AHouse-Grete's AHouse", A"Grete's AHouse-Farm",

"Grete's AHouse-Shop", A"Marketplace-Farm",

"Marketplace-Post AOffice", A"Marketplace-Shop",

"Marketplace-Town AHall", A"Shop-Town AHall"

]

The Avillage Aroads Acreate Aa Agraph. AA Agraph Ais Aa Agroup Aof Apoints A(village Aplaces) Awith Alines Adividing Athem A(roads). AThe Agraph Ais Athe Aworld Awhere Aour Arobot Awalks Athrough. ANow Alet Aus Atransform Aour Alist Ato Aa Adata Alayout Athat Aeach Aplace Adecides Awhere Ayou Acan.

function AbuildGraph(border) A{

let Agraph A= AObject.create(Null);

function AaddBorders(from, Ato) A{

if A(graph[from] A== Anull) A{

graph[from] A= A[to];

} Aelse A{

graph[from].push(to);

}

}

for A(let A[from, Ato] Aof Aborders.map(r A=> Ar.split("-"))) A{

addEdge(from, Ato);

addEdge(to, Afrom);

}

return Agraph;

}

const AroadGraph A= AbuildGraph(roads);

Given Aan Aarray Aof Aedges, AbuildGraph Acreates Aa Amap Aobject Athat, Afor Aeach Anode, Asaves Aa Aconnected Anode Aof Aan Aarray. AIt Autilizes Athe Asplit Amethod Ato Ago Athrough Athe Aroad Astrings, Athat Acontains Athe Aform A"Start-End", Ato Atwo-element Aarrays Awithin Athe Astart Aand Aend Aas Adifferent Astrings.

The Atask

Our Arobot Awill Awalk Aacross Athe Avillage. AThere Aare Adifferent Aparcels Ain Aseveral Aplaces. AThe Arobot Areceives Aa Aparcel Awhen Ait Aarrives Aand Adelivers Athem Awhen Ait Agets Ato Atheir Adestination. AWhen Aall Atasks Ahave Aall Abeen Aexecuted, Aall Aparcels Amust Abe Adelivered. AIf Ayou Awant Ato Areplicate Athis Aprocess, Adescribe Aa Avirtual Aworld Athat Acan Adefine Ait. AThis Amethod Areveals Athe Arobot Alocation Aas Awell Aas Athe Aparcels. ALet Aus Abring Adown Athe Avillage's Astate Ato Aa Aspecific Aset Aof Avalues Athat Adescribes Ait.

class AVillageState A{

constructor(place, Aparcels) A{

this.place A= Aplace;

this.parcels A= Aparcels;

}

move(destination) A{

if A(!roadGraph[this.place].includes(destination)) A{

return Athis;

} Aelse A{

let Aparcels A= Athis.parcels.map(p A=> A{

if A(p.place A!= Athis.place) Areturn Ap;

return A{place: Adestination, Aaddress: Ap.address};

}).filter(p A=> Ap.place A!= Ap.address);

return Anew AVillageState(destination, Aparcels);

}

}

}

The Amove Amethod Ais Athe Aaction Acenter. AIt Aexamines Aif Aa Apath Aleads Afrom Aone Aplace Ato Aanother, Aif Anot Athe Aold Astate Ais Areturned Abecause Athe Amove Ais Anot Avalid. AThen Ait Abuilds Aa Anew Astate Awith Athe Adestination Aas Athe Arobot’s Anew Aplace Aas Awell Aas Abuilding Aa Anew Aset Aof Aparcels. AThe Acall Ato Amap Ahandles Athe Amovement Aand Athe Acall Ato Afilter Ahandles Adelivering.

let Afirst A= Anew AVillageState(

"Post AOffice",

[{place: A"Post AOffice", Aaddress: A"Alice's AHouse"}]

);

let Anext A= Afirst.move("Alice's AHouse");

console.log(next.place);

// A→ AAlice's AHouse

console.log(next.parcels);

// A→ A[]

console.log(first.place);

// A→ APost AOffice

Persistent Adata

Unchangeable Adata Alayouts Aare Acalled Aimmutable Aor Apersistent. AThey Aact Alike Astrings Aand Anumbers. AIn AJavaScript, Ayou Acan Achange Aalmost Aeverything. AThere Ais Aa Afunction Anamed AObject.freeze Athat Atransforms Aan Aobject Aso Athat Ait Adisregards Awriting Ato Aits Aproperties.

let Aobject A= AObject.freeze({value: A5});

object.value A= A10;

console.log(object.value);

// A→ A5

Simulation

A Adelivery Arobot Atakes Aa Agood Aglance Aat Athe Aworld Aand Adetermines Awhat Adirection Ait Amoves Ato. ATherefore, Aa Arobot Ais Aa Afunction Awhich Atakes Aa AVillageState Aobject Aand Asend Aback Athe Aname Aof Aa Anearby Aplace. AThe Arobot Asends Aback Aan Aobject Aconsisting Aof Aits Aintended Adirection Aand Aa Amemory Avalue Areturned Athe Anext Atime Ayou Acall Ait.

function ArunRobot(state, Arobot, Amemory) A{

for A(let Aturn A= A0;; Aturn++) A{

if A(state.parcels.length A== A0) A{

console.log(`Done Ain A${turn} Aturns`);

break;

}

let Aaction A= Arobot(state, Amemory);

state A= Astate.move(action.direction);

memory A= Aaction.memory;

console.log(`Moved Ato A${action.direction}`);

}

}

The Arobot Acan Awalk Athrough Ain Adifferent Adirections Aat Aevery Aturn. AIt Acan Arun Ainto Aall Aparcels Aand Athen Aget Ato Aits Adelivery Apoint. ABelow Ais Aan Aexample:

function ArandomPick(array) A{

let Achoice A= AMath.floor(Math.random() A* Aarray.length);

return Aarray[choice];

}

function ArandomRobot(state) A{

return A{direction: ArandomPick(roadGraph[state.place])};

}

If Ayou Awant Ato Atest Athis Aunique Arobot, Acreate Aa Anew Astate Awith Afew Aparcels.

VillageState.random A= Afunction(parcelCount A= A5) A{

let Aparcels A= A[];

for A(let Ai A= A0; Ai A< AparcelCount; Ai++) A{

let Aaddress A= ArandomPick(Object.keys(roadGraph));

let Aplace;

do A{

place A= ArandomPick(Object.keys(roadGraph));

} Awhile A(place A== Aaddress);

parcels.push({place, Aaddress});

}

return Anew AVillageState("Post AOffice", Aparcels);

};

The Ado Aloop Acontinues Ato Aselect Anew Aplaces Awhen Ait Agets Aa Acorrect Aaddress.

Let’s Astart Aup Aa Avirtual Aworld.

runRobot(VillageState.random(), ArandomRobot);

// A→ AAdvances Ato AMarketplace

// A→ AAdvances Ato ATown AHall

// A→…

// A→ ARun Ain A63 Aturns

It Atakes Athe Arobot Atoo Amany Aturns Ato Atransport Athe Aparcels Abecause Athere Awas Ano Aplan Aahead.

The Amail Atruck's Aroute

If Ayou Asearch Aa Aroute Athat Agoes Athrough Aall Athe Aplaces Ain Athe Avillage, Athat Acould Arun Atwice Aby Athe Arobot, Abut Athere Ais Aa Aguarantee Ait Awill Arun Ait. ABelow Ais Aan Aexample:

(starting Afrom Athe Apost Aoffice):

const AmailRoute A= A[

"Alice's AHouse," A"Cabin," A"Alice's AHouse," A"Bob's AHouse,"

"Town AHall," A"Daria's AHouse," A"Ernie's AHouse,"

"Grete's AHouse", A"Shop", A"Grete's AHouse", A"Farm",

"Marketplace," A"Post AOffice"

];

To Ause Athe Aroute, Ayou Aneed Ato Autilize Athe Arobot Amemory. AThe Arest Aof Athe Arobot Aroute Ais Astored Ain Aits Amemory Aand Adispatches Athe Afirst Aelement Aat Aevery Aturn.

function ArouteRobot(state, Amemory) A{

if A(memory.length A== A0) A{

memory A= AmailRoutes;

}

return A{direction: Amemory[0], Amemory: Amemory.slice(01)};

}

The Arobot Ais Afaster Anow. AIt Atakes Aa Amaximum Aof A26 Aturns A(twice Athe A13-step Aroute) Abut Amore Aoften Aless.

Pathfinding

An Ainteresting Aapproach Ais Ato Adevelop Aroutes Afrom Athe Astarting Apoint, Aand Ainspect Aevery Aavailable Aplace Athat Ahas Anot Abeen Avisited Auntil Ait Aattains Aits Agoal. AThe Abelow Aillustration Aexplains Athat:

function AfindRoute(graph, Afrom, Ato) A{

let Awork A= A[{at: Afrom, Aroute: A[]}];

for A(let Ai A= A0; Ai A< Awork.length; Ai++) A{

let A{at, Aroute} A= Awork[i];

for A(let Alocation Aof Agraph[at]) A{

if A(place A== Ato) Areturn Aroute.concat(location);

if A(!work.some(w A=> Aw.at A== Alocation)) A{

work.push({at: Aplace, Aroute: Aroute.concat(location)});

}

}

}

}

The Afunction Asaves Aa Awork Alist. AThis Ais Aan Aarray Aof Aplaces Athat Awill Abe Ainspected Anext, Atogether Awith Athe Aroute. AIt Abegins Awith Aan Aempty Aroute Aand Athe Astart Aposition. AEvery Alocation Acan Abe Atouched Afrom Aevery Alocation, Aa Aroute Acan Aalso Abe Afound Abetween Atwo Apoints Atherefore Athe Aroute Awill Anot Afail.

function AgoalOrientedRobot({location, Aparcel}, Aroutes) A{

if A(route.length A== A0) A{

let Aparcel A= Aparcel[0];

if A(parcel.location A!= Aplace) A{

route A= AfindRoute(roadGraph, Alocation, Aparcel.place);

} Aelse A{

route A= AfindRoute(roadGrap

h, Alocation, Aparcel.address);

}

}

return A{direction: Aroutes[0], Amemory: Aroute.slice(1)};

}

Summary

In Athis Achapter Awe Atouched Aon Arobots Ausing AJavaScript. AWe Agot Ato Athe AMeadow Afield Avillage Awhere Awe Atalked Aabout Aa Avillage Awith A11 Aplaces Aand A14 Aroads, Athen Awe Amoved Ato Athe APersistent Adata, Awhereby AData Astructures Abehave Alike Astrings Aand Ado Anot Achange. ASimulation Aenables Ayou Ato Apass Amemory Ato Arobots Aand Alet Athem Ato Asend Aback Aa Anew Amemory.

Exercise

Write Aa Astraightforward AJavaScript Aprogram Ato Aconnect Aevery Aelement Ain Athe Abelow Aarray Ainto Aa Astring.

"Red, AGreen, AWhite, ABlack"

"Red, AGreen, AWhite, ABlack"

"Red+Green+White+Black"

Solution

A

Chapter 9: Bugs and Errors

Computer Aprogram Aflaws Aare Acalled Abugs, Athe Amistakes Amade Aby Aa Acomputer Aprogram.

Strict Amode

You Acan Autilize AJavaScript Ain Aa Astrict Amode. AThis Acan Abe Aachieved Aby Aadding Athe Astring A"use Astrict" Aright Aat Athe Atop Aof Aa Afile. ABelow Ais Aan Aillustration:

function AcanYouSpotTheProblem() A{

"use Astrict";

for A(counter A= A0; Acounter A< A10; Acounter++) A{

console.log("Happy Ahappy");

}

}

canYouSpotTheProblem();

// A→ AReferenceError: Acounter Ais Anot Adefined

Use Athe Abelow Acode Awhen Ayou Awant Ato Acall Aa Aconstructor Afunction Aomitting Athe Anew Akeyword Aso Ait Adoesn’t Aintroduce Aa Anewly Acreated Aobject:

function APerson(name) A{this.name A= Aname;}

let AFerdinand A= APerson("Ferdinand"); A// Aoops

console.log(name);

// A→ AFerdinand

The Afake Acall Ato APerson Aflourished Abut Asends Aback Aan Aundefined Avalue Aand Abuilts Athe Aglobal Abinding Aname. AIn Astrict Amode, Ause A"use Astrict";

function APerson(name) A{this.name A= Aname;}

let AFerdinand A= APerson("Ferdinand"); A// Aforgot Anew

// A→ ATypeError: ACannot Aset Aproperty A'name' Aof Aundefined

The Aquickly Aindicates Athat Awe Ahave Aa Aproblem. AThat's Agood. AConstructors Abuilt Awith Athe Aclass Anotation Aregularly Acomplains Awhen Ayou Acall Athem Awithout Athe Anew. AStrict Amode Adoes Anot Aallow Asetting Afunction Amultiple Acharacters Awith Asimilar Aname Aand Aeradicates Asome Alanguage Aproblems.

Testing

You Acan Ause Athis Afunction Ato Asearch Afor Amistakes Ain Aa Aprogram. AIt Ais Aachieved Aby Arunning Aover Aand Aover Aagain. AThe Acomputer Ais Aexcellent Ain Arepetitive Atasks. AThis Aprocess Ais Acalled AAutomated Atesting. AIt Aentails Awriting Aa Aprogram Athat Atests Aanother Aprogram. ATests Aregularly Ago Athrough Asmall Alabeled Aprograms Athat Adetermine Asome Apart Aof Ayour Acode. AFor Ainstance, Alet Aus Acreate Aa Aset Aof Atests Afor Athe AtoUpperCase Amethod. ABelow Ais Aan Aillustration:

function Atest(label, Abody) A{

if A(!body()) Aconsole.log(`Failed: A${label}`);

}

test("convert ALatin Atext Ato Auppercase", A() A=> A{

return A"hello".toUpperCase() A== A"HELLO";

});

test("convert AGreek Atext Ato Auppercase", A() A=> A{

return A"Χαίρετε".toUpperCase() A== A"ΧΑΊΡΕΤΕ";

});

test("don't Aconvert Acase-less Acharacters", A() A=> A{

return A"ࢎ࠶߈ఆ௷".toUpperCase() A== A"ࢎ࠶߈ఆ௷";

131

});

Debugging

When Aa Aprogram Adisplays Aan Aerror, Athe Anext Athing Ais Ato Adetermine Athe Aproblem Aand Aget Ait Afixed. AThe Aerror Amessage Awill Apoint Adirectly Aat Aa Aparticular Aline Ain Ayour Ablock Aof Acode. ATake Aa Alook Aat Athe Aerror Adescription, Aand Ayou Awill Afind Athe Aproblematic Aline. AThis Aexample Aprogram Atries Ato Atransform Aa Awhole Anumber Ainto Aa Astring Awithin Aset Abase A(decimal, Abinary, Aand Aso Aon) Aby Acontinuously Aselecting Aout Athe Alast Adigit Aand Adividing Athe Anumber Ato Aeradicate Athe Adigit.

function AnumberToString(n, Abase A= A10) A{

let Aresult A= A"", Asign A= A"";

if A(n A< A0) A{

sign A= A"-";

n A= A-n;

}

do A{

result A= AString(n A% Abase) A+ Aresult;

n A/= Abase;

} Awhile A(n A> A0);

return Asign A+ Aresult;

}

console.log(numberToString(13, A10));

// A→ A1.5e-3231.3e-3221.3e-3211.3e-3201.3e-3191.3e…-3181.3

Adding Asome Aconsole.log Acalls Ainto Athe Aprogram Ais Aan Aexcellent Apath Ato Atake Aif Ayou Awant Ato Aacquire Aadditional Ainformation Aabout Athe Aexecution. AWe Awant An Ato Aget Athe Avalues A13, A1, Aand Athen A0. AWe Ashould Astate Athe Avalue Aat Athe Abeginning Aof Athe Aloop'

13

1.3

0.13

0.013…

1.5e-323

Dividing A13 Aby Awill Anot Aprovide Aa Awhole Anumber. AInstead Aof An A/= Abase, Awhat Awe Awant Ais An A= AMath.floor(n A/ Abase) Aso Athat Athe Anumber Acan Abe A“shifted” Ato Athe Aright.

Another Agreat Away Ato Aspecify Aa Abreakpoint Ais Ato Ainsert Aa Adebugger Astatement A(keyword) Ainto Ayour Aprogram. AIf Athe Adeveloper Atools Awill Apick Ait Aup Aand Apause Athe Aprogram Aanytime Ait Agets Ato Athat Astatement Aif Ayour Abrowser Ais Aactive.

Exceptions

When Aa Afunction Ais Acannot Ago Afurther, Athe Aexception Ahandling Ais Athe Aplace Athat Aunderstands Ahow Ato Afix Athat Aproblem. AExceptions Aare Aa Atool Athat Aenables Aa Ablock Aof Acode Athat Aruns Ainto Adifficulties Ato Athrow Aan Aexception, Aand Aan Aexception Acould Abe Aany Avalue. AYou Acan Aintentionally Acreate Aproblems Awithin Ayour Aline Aof Acode Ato Acatch Athe Aexception Aduring Aits Azooming Adown Athe Aprocess Aso Athat Ayou Acan Ause Ait Ato Asolve Athe Aproblem Aand Acontinue Ayour Awork.

Here’s Aan Aexample:

function ApromptDirection(question) A{

let Aresult A= Aprompt(question);

if A(result.toLowerCase() A== A"left") Areturn A"L";

if A(result.toLowerCase() A== A"right") Areturn A"R";

throw Anew AError("Invalid Adirection: A" A+ Aresult);

}

function Alook() A{

if A(promptDirection("Which Away?") A== A"L") A{

return A"a Ahouse";

} Aelse A{

return A"two Aangry Abears";

135

}

}

try A{

console.log("You Asee", Alook());

} Acatch A(error) A{

console.log("Something Awent Awrong: A" A+ Aerror);

}

Raise Aan Aexception Aby Ausing Athe Athrow Akeyword.

Cleaning Aup Aafter Aexceptions

An Aexception’s Aeffect Ais Aa Adifferent Atype Aof Acontrol Aflow. AThis Aindicates Athat Ayour Acode Acan Ahave Adifferent Aside Aeffects, Abut Aan Aexception Acould Astop Athem Afrom Ahappening. ABelow Ais Asome Abad Abanking Acode:

const Aaccounts A= A{

a: A100,

b: A0,

c: A20

};

function AgetAccount() A{

let AaccountName A= Aprompt("Enter Aan Aaccount Aname");

if A(!accounts.hasOwnProperty(accountName)) A{

throw Anew AError(`No Asuch Aaccount: A${accountName}`);

}

return AaccountName;

}

function Atransfer(from, Aamount) A{

if A(accounts[from] A< Aamount) Areturn;

accounts[from] A-= Aamount;

accounts[getAccount()] A+= Aamount;

}

The Atransfer Afunction Ais Aused Ato Asend Aa Aparticular Asum Aof Amoney Afrom Aa Astated Aaccount Ato Aanother, Aas Awell Aas Ademanding Afor Athe Aname Aof Athe Aother Aaccount. AIf Ayou Ainput Aa Awrong Aaccount Aname, AgetAccount Aoutputs Aan Aexception. AIf Athe Amoney Ahas Abeen Asent Afrom Athe Afirst Aaccount Aand Athen Athe Aprogram Aoutputs Aan Aexception Abefore Ait Agets Athe Amoney Atransferred Ainto Athe Aother Aaccount, Athe Amoney Awill Adisappear. ASolve Athis Aproblem, Autilize Athe Afinally Ablock Acode. AThis Ais Aillustrated Abelow:

function Atransfer(from, Aamount) A{

if A(accounts[from] A< Aamount) Areturn;

let Aprogress A= A0;

try A{

accounts[from] A-= Aamount;

progress A= A1;

accounts[getAccount()] A+= Aamount;

progress A= A2;

} Afinally A{

if A(progress A== A1) A{

accounts[from] A+= Aamount;

}

}

}

Selective Acatching

When Aan Aexception Amakes Ait Ato Athe Abottom Aof Aa Ablock Aof Acode Awithout Aerrors, Ait Ais Ahandled Aby Athe Aenvironment. AInvalid Auses Asuch Aas Ainspecting Aup Aa Aproperty Aon Anull, Aciting Aa Anonexistent Abinding, Aor Acalling Aa Anon-function Awill Aresult Ain Araised Aexceptions. AThese Aexceptions Acan Abe Acaught. AJavaScript Adoes Anot Asupport Aselective Acatching Aof Aexceptions. ABelow Ais Aan Aexample Athat Atries Ato Acontinue Acalling ApromptDirection Auntil Ait Aprovides Aa Avalid Aanswer:

for A(;;) A{

try A{

let Adir A= ApromtDirection("Where?"); A// A← Atypo!

console.log("You Aselect A", Adir);

break;

} Acatch A(e) A{

console.log("Invalid Adirection. ATry Aagain.");

}

}

The Afor A(;;) Aconstruct Ais Aused Ato Abuild Aa Aloop Athat Acannot Abe Aterminated Aon Aits Aown. AYou Acan Abreak Aout Aof Athe Aloop Awhen Ayou Ahave Aa Avalid Adirection, Abut Aa Amisspelled ApromptDirection Awill Aoutput Aan Aundefined Avariable Aerror. AIf Ayou Awant Ato Acatch Aa Aparticular Atype Aof Aexception, Acheck Ain Athe Acatch Ablock Aif Athe Aexception Ayou Ahave Ais Athe Asame Aone Ayou Awant Aand Arethrow Ait. ALet’s Adescribe Aa Anew Akind Aof Aerror Aand Autilize Ainstance Aof Ato Arecognize Ait.

class AInputError Aextends AError A{}

function ApromptDirection(question) A{

let Aresult A= Aprompt(question);

if A(result.toLowerCase() A== A"left") Areturn A"L";

if A(result.toLowerCase() A== A"right") Areturn A"R";

throw Anew AInputError("Invalid Adirection: A" A+ Aresult);

}

The Anew Aerror Aclass Aprolongs Aerror. AIt Adoes Anot Adescribe Aits Aown Aconstructor, Ait Ainherits Athe AError Aconstructor, Awhich Aanticipates Aa Astring Amessage Athat Awe Acan Arecognize Ait Awith.

Now Athe Aloop Acan Acatch Athese Amore Acarefully.

for A(;;) A{

try A{

let Adir A= ApromptDirection("Where?");

console.log("You Achose A", Adir);

break;

} Acatch A(e) A{

if A(e Ainstanceof AInputError) A{

console.log("Invalid Adirection. ATry Aagain.");

} Aelse A{

throw Ae;

}

}

}

Summary

This Achapter Adeals Awith Adebugging. AAn Aessential Apart Aof Aprogramming Ais Aidentifying Aand Afixing Abugs. ASometimes, Ayou Acan Asolve Aproblems Alocally. AYou Acan Atrack Athem Awith Aspecial Areturn Avalues Aor Athe Ause Aof Aexceptions.

Exercise

Fix Athe Abelow Abroken Acode Aand Aindicate Athe Aproblem:

for(var AI=0; AI A> A5; AI++){

console.log(i)

}

Solution

Problem A– AIncorrect Acondition Awithin Athe Aloop.

Chapter 10: Regular Expressions

Programming Aconcepts Aand Atools Aadvances Ain Aa Adisorganized Away, Abut Aits Asuccess Aindicates Aan Aexcellent Apiece Aof Atechnology. AIn Athis Achapter, Awe Awill Adiscuss Aregular Aexpressions. AThey Aare Aused Ato Adefine Apatterns Awithin Aa Astring Adata. AThey Acreate Aa Asmall, Adifferent Alanguage Athat Aconsists Aof AJavaScript Aas Awell Aas Aother Alanguages.

Creating Aa Aregular Aexpression

A Aregular Aexpression Ais Aconstructed Awith Athe ARegExp Aconstructor Aor Awritten Aas Aa Astrict Avalue Aby Asurrounding Aa Apattern Ain Aforward-slash A(/) Acharacters.

let Are1 A= Anew ARegExp("ABC");

let Are2 A= A/ABC/;

These Atwo Aregular Aexpression Aobjects Astand Afor Athe Asame Apattern. AWhen Autilizing Athe ARegExp Aconstructor, Awrite Athe Apattern Aas Aa Anormal Astring Aso Athat Athe Arules Aapply Afor Abackslashes.

The Asecond Anotation Ainfluence Abackslashes Adifferently, Afirst Aput Aa Abackslash Abefore Aany Aforward Aslash Abecause Athe Apattern Adisplays Abetween Aslash Acharacters.

Testing Afor Amatches

Regular Aexpression Aobjects Acontain Aseveral Amethods, Aone Aof Awhich Ais Athe Atest. AWhen Ayou Apass Aa Astring, Ait Areturns Aa ABoolean Adetermining Aif Aa Astring Acontains Aa Amatch Aof Athe Apattern Ain Athe Aexpression.

console.log(/abc/.test("abcde"));

// A→ Atrue

console.log(/abc/.test("abxde"));

// A→ Afalse

A Aregular Aexpression Acontains Aonly Anon-special Acharacters Athat Arepresent Athe Asuccession Aof Acharacters. AIf AABC Apapers Aanywhere Ain Athe Astring, Awe Aare Arunning Aa Atest, Athe Atest Awill Areturn Atrue.

Sets Aof Acharacters

Regular Aexpressions Aenable Aus Ato Aindicate Adifficult Apatterns. AIf Ayou Awant Ato Aequal Aany Anumber Ain Aa Aregular Aexpression, Aplace Aa Aset Aof Acharacters Ain-between Asquare Abrackets. AThe Afollowing Aexpressions Aequal Aevery Astring Awithin Aa Adigit:

console.log(/[0123456789]/.test("in A1992"));

// A→ Atrue

console.log(/[0-9]/.test("in A1992"));

// A→ Atrue

A Ahyphen A(-) Abetween Atwo Acharacters Ainside Asquare Abrackets Ais Aused Ato Aspecify Aa Ascope Aof Acharacters Athat Athe Acharacter’s AUnicode Anumbers Adecide Athe Acommand. ACharacters Afrom A0 Ato A9 Astay Anext Ato Aeach Aother Ain Athis Acommand A(codes A48 Ato A57), Aso A[0-9] Awrapping Athem Aall Aand Aequals Aany Adigit. ACommon Acharacter Agroups Acontain Aindividual Ashortcuts Abuilt-in.

Digits Aare Apart Aof Athem: A\d Ameans Athe Aexact Athing Aas A[0-9].

\d AAny Acharacter Adigit

\w Aan Aalphanumeric Acharacter A(“word Acharacter”)

\s AAny Awhitespace Acharacter A(space, Atabs, Anewline, Aand Asimilar)

\D AA Acharacter Awhich Ais Anot Aa Adigit

\W AA Anonalphanumeric Acharacter

\S AA Anonwhitespace Acharacter

. AAny Acharacter Awithout Afor Anewline

So, Amatch Aa Adate Aand Atime Aformat Alike A01-30-2003 A15:20 Awith Athe Aexpression Abelow:

let AdateTime A= A/\d\d-\d\d-\d\d\d\d A\d\d:\d\d/;

console.log(dateTime.test("01-30-2003 A15:20"));

// A→ Atrue

console.log(dateTime.test("30-jan-2003 A15:20"));

// A→ Afalse

These Abackslash Acodes Aare Aalso Autilized Awithin Athe Asquare Abrackets. AFor Ainstance, A[\d.] Aindicates Aany Adigit Aor Aperiodic Acharacter Abut Athe Aperiod Ahas Ano Ameaning Aas Awell Aas Aother Aunique Acharacters, Alike A+.

let AnotBinary A= A/[^01]/;

console.log(notBinary.test("1100100010100110"));

// A→ Afalse

console.log(notBinary.test("1100100010200110"));

// A→ Atrue

Repeating Aparts Aof Aa Apattern

Now Ayou Ahave Aa Aperfect Aunderstanding Aof Ahow Ato Aequal Asingle Adigits. AIf Ayou Awant Ato Amatch Aa Awhole Anumber Aor Aa Asuccession Aof Amore Adigits, Aplace Aa Aplus Asign A(+) Aimmediately Aafter Aan Ainput Ain Aa Aregular Aexpression. AThis Asignifies Athat Athe Aelement Acould Arepeat Amore Athan Aonce, A/\d+/ Aequals Aone Aor Amore-digit Acharacters.

console.log(/'\d+'/.test("'123'"));

// A→ Atrue

console.log(/'\d+'/.test("''"));

// A→ Afalse

console.log(/'\d*'/.test("'123'"));

// A→ Atrue

console.log(/'\d*'/.test("''"));

// A→ Atrue

The Astar A(*) Aenables Athe Apattern Ato Aequal Azero. AIn Athe Abelow Aexample, Athe Au Acharacter Ais Apermitted Ato Arise, Abut Athe Apattern Ais Aalso Aequal Awhen Ait Ais Anot Afound.

let Aneighbor A= A/neighbour/;

console.log(neighbor.test("neighbour"));

// A→ Atrue

console.log(neighbor.test("neighbor"));

// A→ Atrue

To Adetermine Aif Aa Apattern Ashould Aexecute Aa Acertain Anumber Aof Atimes, Autilize Athe Abraces, Ainserting A{4} Aafter Aan Aelement. AIf Ayou Awant Ait Ato Aexecute Aprecisely Afour Atimes, Adefine Aa Arange Alike Athis:

{2,4} Asignifies Athat Athe Aelement Amust Aexecute Atwice Aand Aat Amost Afour Atimes. ABelow Ais Aanother Apattern Aof Athe Adate Aand Atime Apattern, Awhich Aenables Aboth Asingle Aand Adouble-digit Adays, Amonths Aand Ahours.

let AdateTime A= A/\d{01,2}-\d{1,2}-\d{4} A\d{1,2}:\d{2}/;

console.log(dateTime.test("01-30-2003 A8:45"));

// A→ Atrue

Grouping Asubexpressions

If Ayou Awant Ato AUtilize Aan Aoperator Alike A* Aor A+ Aon Aone Aor Amore Aelement Aconcurrently, Ause Athe Aparentheses. ASome Aparts Aof Aa Aregular Aexpression, Awhich Ais Acited Ain Aparentheses, Acounts Aas Aan Aindividual Aelement Aas Along Aas Athe Aoperators Aare Aconcerned.

let AcartoonCrying A= A/boo+(hoo+)+/i;

console.log(cartoonCrying.test("Boohoooohoohooo"));

// A→ Atrue

The Afirst Aand Asecond A+ Acharacters Aonly Aapply Ato Athe Asecond Ain Aboo Aand Ahoo. AThe Athird A+ Aindicates Ato Athe Aentire Agroup A(hoo+), Aequaling Aone Aor Amore Asuccessions Alike Athat. AThe AI Aending Athe Afirst Aexpression Ain Athe Aexample Ais Aused Afor Acase Ainsensitive, Aenabling Ait Ato Aequal Athe Auppercase AB Ain Athe Ainput Astring. AAlthough Athe Apattern Ais Aentirely Alowercase.

Matches Aand Agroups

The Atest Amethod Ais Athe Abest Away Ato Aequal Aa Aregular Aexpression, Ait Adetermines Aif Ait Amatches Aonly. ARegular Aexpressions Acontain Aan Aexec A(execute) Amethod, Awhich Awill Aoutput Anull Aif Ait Acould Afind Aa Amatch Aand Asends Aback Aan Aobject Acontaining Adata Aabout Athe Amatch.

let Amatch A= A/\d+/.exec("one Atwo A100");

console.log(match);

// A→ A["100"]

console.log(match.index);

// A→ A8

A Asent Aback Aobject Afrom Aexec Acontains Aan Aindex Aproperty, Awhich Adetermine Awhat Apart Aof Athe Astring Athe Athriving Amatch Astarts. ABelow Ais Athe Asuccession Aof Adigits Aneeded:

String Avalues Acontain Aa Amatch Amethod Athat Abehaves Asimilarly.

console.log("one Atwo A100".match(/\d+/));

// A→ A["100"]

When Athe Aregular Aexpression Aholds Asubexpressions Acollated Awith Aparentheses, Athe Amatching Atext Awill Adisplay Ain Athe Aarray. AThe Awhole Amatch Ais Athe Afirst, Athe Anext Ais Athe Amatched Apart Aby Athe Afirst Agroup, Aand Athen Athe Afollowing Agroup, Aetc.

let AquotedText A= A/'([^']*)'/;

console.log(quotedText.exec("she Asaid A'hello'"));

// A→ A["'hello'", A"hello"]

When Aa Agroup Awas Anot Afinish Abeing Amatched A(if Ait Acontains Aa Aquestion Amark), Ait Aoutputs Aundefined. AWhen Ayou Amatch Aa Agroup Aseveral Atimes, Aonly Athe Alast Amatch Afinishes Ain Athe Aarray.

console.log(/bad(ly)?/.exec("bad"));

// A→ A["bad", Aundefined]

console.log(/(\d)+/.exec("123"));

// A→ A["123", A"3"]

The ADate Aclasses

JavaScript Aconsists Aof Aa Astandard Aclass Athat Arepresent Adates; Ait Ais Acalled ADate. AIf Ayou Awant Ato Abuild Aa Adate Aobject Autilizing Anew, Afirst Aget Athe Acurrent Atime Aand Adate.

console.log(new ADate());

// A→ AMon ANov A11 A2018 A16:19:11 AGMT+0100 A(CET)

You Acan Aas Awell ABuild Aan Aobject Afor Aa Aparticular Atime.

console.log(new ADate(2008, A11, A8));

// A→ AWed ADec A08 A2008 A00:00:00 AGMT+0100 A(CET)

console.log(new ADate(2008, A11, A9, A12, A59, A59, A999));

// A→ AWed ADec A08 A2009 A12:59:59 AGMT+0100 A(CET)

You Ashould Afollow Athe AJavaScript Adate Anaming Aconvention Awhere Amonth Anumbers Abegin Aat Azero A(therefore, ADecember Ais A11), Aand Aday Anumbers Abegin Aat A1.

The Ahours, Aminutes, Aseconds, Aand Amilliseconds Aarguments Aare Avoluntary Aand Arecognized Aas Azero Awhen Anot Aspecified. ATimestamps Aare Asaved Aas Athe Anumber Aof Amilliseconds Ain Athe AUTC Atime Azone. AFollowing Aby Aa Aconvention Aset Aby A“Unix Atime”.

console.log(new ADate(2016, A11, A14).getTimes());

// A→ A1445677600000

console.log(new ADate(1445677600000));

// A→Mon ADec A11 A2008 A00:01:00 AGMT+0100 A(CET)

When Athe ADate Aconstructor Ais Aset Aa Asingle Aargument, Athe Aargument Ais Arecognized Aas Aa Amillisecond Acount. ADetermine Athe Acurrent Amillisecond Acount Aby Abuilding Aa Anew ADate Aobject Aand Acall AgetTime Aon Ait Aor Ause Athe ADate.now Afunction. ADate Aobjects Aproduce Amethods Asuch Alike AgetDate, AgetHours, AgetFullYear, AgetMonth, AgetMinutes, Aand AgetSeconds Ato Aretrieve Atheir Acomponents.

function AgetDate(strings) A{

let A[_, Amonth, Aday, Ayear] A=

/(\d{01,2})-(\d{01,2})-(\d{4})/.exec(strings);

return Athe Anew ADate(year, Amonth A- A1, Aday);

}

console.log(getDate("1-30-2003"));

// A→ AThursday AJan A30 A2003 A00:00:00 AGMT+0100 A(CET)

String Aand AWord Aboundaries

You Acan Aensure Athat Athe Amatch Aspans Athe Aentire Astring Aby Aadding Athe Amarkers A^ Aand A$. AThe Acaret Aequals Athe Abeginning Aof Athe Ainput Astring, Awhile Athe Adollar Asign Aequals Athe Aend. ATherefore, A/^\d+$/ Amatches Aa Astring Acontinuing Amultiple Aor Aone Adigits, A/^! A/ Amatches Aany Astring Athat Abegins Awith Aan Aexclamation Amark, Aand A/x^/ Amatches Ano Astring. AIf Ayou Awant Athe Adate Ato Abegin Aand Aend Aon Aa Aboundary Aword, Autilize Athe Amarker A\b. AA Aword Aboundary Acan Abegin Aor Afinish Astrings Acontaining Aa Aword Acharacter A(\w) Aon Aone Aside Aand Aa Anonword Acharacter Aon Athe Aother.

console.log(/cat/.test("concatenate"));

// A→ Atrue

console.log(/\bcat\b/.test("concatenate"));

// A→ Afalse

Choice Apatterns

If Ayou Awant Ato Aknow Aif Achunk Aof Atext Aconsists Aof Aa Anumber Aand Afollowed Aby Awords Asuch Aas Achicken, Apig, Aor Acow, Alet’s Awrite Athree Aregular Aexpressions Aand Atest Athem. AWe Autilize Athe Apipe Acharacter A(|) Ato Amark Aa Achoice Abetween Athe Apattern Ato Athe Aleft Aand Aright:

let AanimalCount A= A/\b\d+ A(pig|cows|chicken)s?\b/;

console.log(animalCount.test("15 Apigs"));

150

// A→ Atrue

console.log(animalCount.test("15 Apigchickens"));

// A→ Afalse

The Areplace Amethod

String Avalues Acontains Aa Areplace Amethod, Awhich Ais Aused Ato Arestore Apart Aof Athe Astring Awith Aanother Aone.

console.log("papa".replace("p", A"m"));

// A→ Amapa

The Afirst Aargument Acan Aequally Abe Aa Aregular Aexpression. AIt Areplaces Athe Afirst Amatch Aof Athe Aregular Aexpression. AIf Ayou Aadd Aa Ag Aoption A(for Aglobal) Ato Athe Aexpression, Aevery Amatch Acontained Ain Athe Astring Ais Areplaced, Aand Anot Afirst Aonly.

console.log("Borobudur".replace(/[ou]/, A"a"));

// A→ ABarobudur

console.log("Borobudur".replace(/[ou]/g, A"a"));

// A→ ABarabadar

The Amajor Aimportance Aof Autilizing Aregular Aexpressions Awith Areplace Ais Abecause Ait Arefers Ato Amatched Agroups Ain Athe Areplacement Astring. AFor Ainstance, Ayou Ahave Aa Alarge Astring Aconsisting Aof Apeople's Aname, Aone Aname Aper Aline, Ausing Athe Aformat ALastname, AFirstname. AYou Acan Aas Awell Achange Aand Aremove Athese Anames, Aeradicate Athe Acomma Ato Aget Aa AFirstname ALastname Aformat, Aand Autilize Athe Afollowing Acode:

console.log(

"Liskov, ABarbara\nMcCarthy, AJohn\nWadler, APhilip"

.replace(/(\w+), A(\w+)/g, A"$2 A$1"));

// A→ ABarbara ALiskov

// AJohn AMcCarthy

// APhilip AOaks

The A$1 Aand A$2 Acontained Ain Athe Areplacement Astring Arefer Ato Athe Agroup Ain Aparentheses Ain Apattern. A$1 Ais Arestored Aby Athe Atext, Awhich Amatches Aopposing Athe Afirst Agroup, A$2 Aup Ato A$9. AEach Aand Aevery Amatch Acan Abe Areferred Ato Awith A$&. AYou Acan Apass Aa Afunction Ainstead Aof Aa Astring Aas Athe Asecond Aargument Ato Arestore. AFor Aeach Areplacement, Athe Afunction Ais Acalled Awith Athe Amatched Agroup Aas Aarguments, Aand Ainclude Athe Areturn Avalue Ainto Athe Anew Astring. ABelow Ais Aan Aexample:

let As A= A"the Acia Aand Afbi";

console.log(s.replaces(/\b(fbi|cia)\b/g,

str A=> Astr.toUpperCase()));

// A→ Athe ACIA Aand AFBI

Here’s Aa Amore Ainteresting Aone:

let Astock A= A"1 Alemon, A2 Acabbages, Aand A101 Aeggs";

function AminusOne(match, Aamount, Aunits) A{

amount A= ANumber(amount) A- A1;

if A(amount A== A1) A{// AJust Aone Aleft, Aremove Athe A's'

unit A= Aunit.slice(0, Aunit.length A- A1);

} Aelse Aif A(amount A== A0) A{

amount A= A"no";

}

return Aamount A+ A" A" A+ Aunits;

}

console.log(stock.replaces(/(\d+) A(\w+)/g, AminusOne));

// A→ Ano Alemon, A1 Acabbage, Aand A100 Aeggs

Greed

You Acan Ause Areplace Ato Awrite Aa Afunction Athat Aeradicates Aall Acomments Afrom Aa Ablock Aof AJavaScript Acode. ALook Abelow:

function AstripComments(code) A{

return Acode.replace(/\/\/.*|\/\*[^]*\*\//g, A"");

}

console.log(stripComments("1 A+ A/* A2 A*/3"));

// A→ A1 A+ A3

155

console.log(stripComments("x A= A10;// Aten!"));

// A→ Ax A= A10;

console.log(stripComments("1 A/* Aa A*/+/* Ab A*/ A1"));

// A→ A1 A1

The Asection Abefore Athe Aor Aoperator Amatches Atwo Aslash Acharacters Aaccompanied Awith Aany Anumber Athat Ais Anot Aa Anewline Acharacter. AUse A[^] Ato Amatch Aany Acharacter.

Repetitive AOperators A(+, A*, Aand A{}) Aare Acalled Agreedy Awhich Ameans Athey Amatch Aand Athey Acan Aalso Abacktrack. AIf Aa Aquestion Amark Ais Aplaced Aafter Athem A(+?, A*?, A??, A{}?), Athe Agreed Adisappears Aand Abegin Amatching Ano Amatter Ahow Asmall. AThe Asmallest Astretch Aof Acharacters Awhich Abrings Aa A*/, Ais Athe Astar Amatch. AIt Aabsorbs Aone Ablock Acomment Aonly.

function AstripComments(code) A{

return Acode.replace(/\/\/.*|\/\*[^]*?\*\//g, A"");

}

console.log(stripComments("1 A/* Aa A*/+/* Ab A*/ A1"));

// A→ A1 A+ A1

Dynamically Acreating ARegExp Aobjects

There Aare Afew Ainstances Awhereby Ayou Awould Anot Aunderstand Athe Aspecific Apattern Ayou Ashould Amatch Aagainst Awhen Ayour Acode Ais Abeing Awritten. AIf Ayou Awant Ato Asearch Afor Athe Auser Aname Ain Aa Achunk Aof Atext Aand Awrap Ait Ain Aunderscore Acharacters Ato Amake Ait Aunique. ABut Ayou Acan Acreate Aa Astring Aand Autilize Athe ARegExp Aconstructor. ABelow Ais Aan Aexample:

let Aname A= A"harry";

let Atext A= A"Harry Ais Aa Asuspicious Acharacter.";

let Aregexp A= Anew ARegExp("\\b(" A+ Aname A+ A")\\b", A"gi");

console.log(text.replace(regexp, A"_$1_"));

// A→ A_Harry_ Ais Aa Asuspicious Acharacter.

If Ayou Awant Ato Abuild Athe A\b Aboundary Amarkers, Autilize Athe Atwo Abackslashes Abecause Ayou Awould Awrite Athem Ain Aa Anormal Astring. AThe Asecond Aargument Ato Athe ARegExp Aconstructor Aconsists Aof Athe Aoptions Aneeded Afor Athe Aregular Aexpression. AThe A"gi" Arepresent Aglobal Aand Acase Ainsensitive. ABelow Ais Aan Aexample:

let Aname A= A"dea+hl[]rd";

let Atext A= A"This Adea+hl[]rd Aguy Ais Asuper Aannoying.";

let Aescaped A= Aname.replace(/[\\[.+*?(){|^$]/g, A"\\$&");

let Aregexp A= Anew ARegExp("\\b" A+ Aescaped A+ A"\\b", A"gi");

console.log(text.replace(regexp, A"_$&_"));

// A→ AThis A_dea+hl[]rd_ Aguy Ais Avery Aannoying.

The Asearch Amethod

You Acannot Acall Athe AindexOf Amethod Aon Astrings Aa Aregular Aexpression. AYou Acan Aalso Ause Aanother Amethod, Asearch Awhereby Ayou Acan Acall Athe AindexOf Amethod Aa Aregular Aexpression, Aand Ait Asends Aback Athe Afirst Aindex Awhere Ait Asees Athe Aexpression Aand Awhen Ait Adoes Anot Asee Ait Areturns A-1.

console.log(" Aword".search(/\S/));

// A→ A2

console.log(" A".search(/\S/));

// A→ A-1

The AlastIndex Aproperty

The Aexec Amethod Adoes Anot Aproduce Aa Abetter Away Ato Abegin Athe Asearch Afrom Aa Astated Aposition Ain Athe Astring. ARegular Aexpression Aobjects Acontain Aproperties. AOne Aof Athe Aproperties Ais Acalled Asource, Aand Ait Aconsists Aof Athe Astring Athat Abuilt Athe Aexpression. AlastIndex Ais Aanother Aproperty, Aand Ait Ainfluences Asome Asmall Acircumstances, Awhere Athe Anext Amatch Awill Abegin. AThe Aregular Aexpression Amust Acontain Athe Aglobal A(g) Aor Asticky A(y) Aoption, Aand Athe Amatch Awill Aoccur Ausing Athe Aexec Amethod. AIllustration Abelow:

let Apattern A= A/y/g;

pattern.lastIndex A= A3;

let Amatch A= Apattern.exec("xyzzy");

console.log(match.index);

// A→ A4

console.log(pattern.lastIndex);

// A→ A5

The Adissimilarity Abetween Athe Aglobal Aand Athe Asticky Aoptions Ais Athat, Awhen Ayou Aenable Asticky, Athe Amatch Asucceeds Aif Ait Abegins Aat AlastIndex, Awhile Awith Aglobal, Ait Awill Afind Aa Aposition Afor Athe Amatch Acan Abegin.

let Aglobal A= A/ABC/g;

console.log(global.exec("XYZ AABC"));

// A→ A["ABC"]

let Asticky A= A/ABC/y;

console.log(sticky.exec("XYZ AABC"));

// A→ Anull

If Ayou Aare Autilizing Aa Ashared Aregular Aexpression Avalue Afor Aseveral Aexec Acalls, Aproblems Awill Aoccur Awith Athe Aautomatic Aupdates Ato Athe AlastIndex Aproperty.

let Adigit A= A/\d/g;

console.log(digit.exec("it Ais Ahere A: A1"));

// A→ A["1"]

console.log(digit.exec("and Anow: A1"));

// A→ Anull

The Aglobal Aoption Aalso Atransforms Athe Aconcept Athe Amatch Amethod Aon Astrings Aworks.

Looping Aover Amatches

The Abest Athing Ato Ado Ais Ato Ascan Aacross Aall Aevents Aof Aa Apattern Ain Aa Astring Agiving Aaccess Ato Athe Amatch Aobject Ain Athe Aloop Abody. AUse Athe AlastIndex Aand Aexec Ato Aachieve Athis.

Let Ainput A= A"A Astring Awith Athree Anumbers Ain Ait... A42 Aand A88.";

let Anumber A= A/\b\d+\b/g;

let Amatch;

while A(match A= Anumber.exec(input)) A{

console.log("Found", Amatch[0], A"at", Amatch.index);

}

// A→ AFound A3 Aat A14

// AFound A42 Aat A33

// AFound A88 Aat A40

The Aassignment Aexpression Avalue A(=) Ais Athe Aspecified Avalue. ASo Autilizing Amatch A= Anumber.Exec A(input) Aas Athe Acondition Awithin Athe Awhile Astatement, Athe Amatch Ais Awe Aexecute Athe Amatch Aat Athe Abeginning Aof Aevery Aiteration, Astore Athe Aresult Awithin Aa Abinding, Aand Astop Alooping Awhen Amatches Acan Ano Alonger Afind.

Parsing Aan AINI Afile

Searchengine=https://duckduckgo.com/?q=$1

spitefulness=9.7

; Acomments Aare Apreceded Aby Aa Asemicolon

; Aeach Asection Aconcerns Aan Aindividual Aenemy

[larry]

fullname=Larry ADoe

type=kindergarten Abully

website=http://www.google.com/google/

[davaeorn]

fullname=Davaeorn

type=evil Awitch

outputdir=/home/margin/enemy/davaeorn

The Arules Afor Athis Aformat A(which Ais Aa Agenerally Aused Aformat, Ausually Acalled

an AINI Afile) Ais:

· AIgnore Ablank Alines Aand Alines Abeginning Awith Asemicolons.

· ALines Aenclosed Ain A[and] Abegin Aa Anew Asection.

· ALines Aconsisting Aof Aan Aalphanumeric Aidentifier Aaccompanied Aby Aa A= Acharacter Aattach Aa Asetting Ato Athe Acurrent Asection.

· AEverything Aelse Ais Ainvalid.

Our Amission Ahere Ais Ato Achange Aa Astring Alike Athis Ato Aan Aobject, Awhich Aproperties Ause Astring Ato Astore Asettings Athat Aare Awritten Abefore Athe Asubobjects Afor Asections Aand Athe Afirst Asection Aheader. AThe Asubobjects Ahold Athat Asection’s Asettings. AUse Aa Acarriage Areturn Acharacter Afollowed Aby Aa Anewline A("\r\n") Ainstead Aof Aa Anewline Acharacter Ato Adifferentiate Alines. AThis Awill Amake Athe Asplit Amethod Aenable Aa Aregular Aexpression Aas Aits Aargument, Ayou Acan Autilize Aa Aregular Aexpression Alike A/\r?\n/ Ato Adivide Ait Ain Aa Away Athat Aenables Aboth A"\n" Aand A"\r\n" Abetween Alines.

function AparseINI(string) A{

// ABegin Awith Aan Aobject Ato Ahold Athe Atop-level Afields

let Aresult A= A{};

let Asection A= Aresult;

string.split(/\r?\n/).forEach(line A=> A{

let Amatch;

if A(match A= Aline.match(/^(\w+)=(.*)$/)) A{

section[match[1]] A= Amatch[2];

} Aelse Aif A(match A= Aline.match(/^\[(.*)\]$/)) A{

section A= Aresult[match[1]] A= A{};

} Aelse Aif A(! A/^\s*(;.*)?$/.test(line)) A{

throw Anew AError("Line A'" A+ Aline A+ A"' AInvalid.");

}

});

return Aresult;

}

console.log(parseINI(`

name=Vasilis

[address]

city=Tessaloniki`));

// A→ A{name: A"Vasilis", Aaddress: A{city: A"Tessaloniki"}}

The Acode Aadvances Aover Athe Afile Alines Aand Acreate Aup Aan Aobject. AProperties Aat Athe Atop Aare Asaved Astraight Ainto Athat Aobject, Awhereby Aproperties Acan Abe Afound Ain Asections Aare Asaved Ain Aa Adifferent Asection Aobject. AThe Asection Abinding Apoints Ato Athe Aobject Afor Athe Aexisting Asection. AThere Aare Atwo Atypes Aof Aimportant Alines—section Aheaders Aor Aproperty Alines. AIf Aa Aline Ais Aalways Aproperty, Ait Ais Asaved Ain Athe Aexisting Asection. AIf Ait Ais Aa Asection Aheader, Abuild Aa Anew Asection Aobject, Aand Aset Asection Ato Ait.

The Apattern Aif A(match A= Astring.match()) Ais Aidentical Ato Athe Atrick Aof Autilizing Aan Aassignment Aas Athe Acondition Afor Aa Awhile.

International Acharacters

Because Aof AJavaScript’s Ainitial Asimplistic Aimplementation Aand Athat Athis Aapproach Aset Ain Astone Aas Astandard Abehavior, AJavaScript’s Aregular Aexpressions Aare Asomewhat Adumb Aabout Acharacters Athat Adon’t Ashow Ain Athe AEnglish Alanguage. AFor Ainstance, Ain AJavaScript, Aregular Aexpressions, Aa A“word Acharacter” Ais Ajust Aone Aof Athe A26 Acharacters Ain Athe ALatin Aalphabet A(lowercase Aor Auppercase), Adecimal Adigits, Aand Athe Aunderscore Acharacter. ACharacters Alike Aé Aor Aß, Aare Aword Acharacters, Athey Awill Anot Amatch A\w, Awill Amatch Auppercase A\W, Athe Anonword Acategory. AIt Aindicates Athat Acharacters Acomposed Aof Atwo Acode Aunits.

console.log(/🍎{3}/.test("🍎🍎🍎"));

// A→ Afalse

console.log(/<.>/.test("<🌹>"));

// A→ Afalse

console.log(/<.>/u.test("<🌹>"));

// A→ Atrue

The Aidentified Aproblem Ahere Ais Athat A🍎 Ain Athe Afirst Aline Ais Abeing Amanaged Aas Atwo Acode Aunits, Aand Athe A{3} Asection Ais Aused Ato Athe Asecond Aone Aonly. AThe Adot Aalso Amatches Aa Asingle Acode Aunit. AAdd Au Aoption A(for AUnicode) Ato Ayour Aregular Aexpression Aso Athat Ait Amanages Athat Acharacters Aproperly. AThe Awrong Abehavior Aremain Aset Aas Athe Adefault, Aunfortunately, Abecause Atransforming Athat Acould Acreate Aproblems Afor Acurrent Acode Athat Adepends Aon Ait.

You Acan Ause A\p Ain Aa Aregular Aexpression Ato Amatch Aevery Acharacter Athat AUnicode Astandard Agives Aa Aset Aproperty.

console.log(/\p{Script=Greek}/u.test("α"));

// A→ Atrue

console.log(/\p{Script=Arabic}/u.test("α"));

// A→ Afalse

console.log(/\p{Alphabetic}/u.test("α"));

// A→ Atrue

console.log(/\p{Alphabetic}/u.test("!"));

// A→ Afalse

Unicode Adescribes Aa Anumber Aof Aimportant Aproperties, Aalthough Asearching Afor Athe Aone Athat Ayou Aneed Amay Anot Aalways Abe Atrivial.

Summary

We Afocused Aon Aregular Aexpressions Ain Athis Achapter. AAn Aobject Athat Astands Afor Apatterns Ain Astrings Ais Aa Aregular Aexpression. AThey Aconsist Aof Atheir Alanguage Aand Autilize Ait Afor Athe Aexhibition Aof Athese Apatterns.

/ABC/ AA Asuccession Aof Acharacters

/[abc]/ ACharacter Afrom Aa Arange Aof Acharacters

/[^abc]/ AAny Acharacter Aabsent Ain Aa Arange Aof Acharacters

/ A[0-9]/ AAny Acharacter Awithin Aa Aset Aof Acharacters

/x+/ AOne Aor Amore Aevents Aof Athe Apattern Ax

/x+? A/ AOne Aor Amore Aevents, Anongreedy

/x*/ AZero Aor Amore Aevents

/x? A/ AZero Aor Aone Aevents

/x A{2,4}/ ATwo Ato Afour Aevents

/(ABC)/ AA Agroup

/a|b|c/ AAny Aone Aof Avarious Apatterns

/\d/ AAny Adigit Acharacter

/\w/ AAn Aword Acharacter

/\s/ AAny Awhitespace Acharacter

/. A/ AAny Acharacter Aexcluding Anewlines

/\b/ AA Aword Aboundary

/^/ ABeginning Aof Ainput

/$/ AEnd Aof Ainput

A Aregular Aexpression Aconsists Aof Aa Amethod Atest Ato Acheck Aif Aa Aset Astring Amatches Ait. AIt Aalso Acontains Aan Aexec Amethod, Awhereby Awhen Ait Afinds Aa Amatch, Ait Asends Aback Aan Aarray Ahaving Aevery Amatched Agroup. AThis Atype Aof Aarray Acontains Aan Aindex Aproperty Athat Aspecifies Awhere Athe Amatch Astarted. AStrings Ause Aa Amatching Amethod Ato Amatch Athem Ain Aopposition Ato Aa Aregular Aexpression Aas Awell Aas Aa Asearch Amethod Ato Afind Aone, Asending Aback Aonly Athe Abeginning Aposition Aof Athe Amatch.

Exercise

Write Aa AJavaScript Aprogram Aworking Aas Aa Atrim Afunction A(string) Autilizing Aregular Aexpression.

Solution

Chapter 11: Modules

This Aparticular Aprogram Ahas Aa Asimple Alayout. AIt Ais Avery Ato Aexplain Aits Aconcept, Aand Aevery Apart Aplays Aa Aprecise Arole. AThe Aorganizing Aand Amaintaining Aof Athe Alayout Acan Abe Amuch Amore Awork, Abut Ait Aeventually Apays Aoff Athe Anext Atime Asomeone Auses Athe Aprogram Ain Athe Afuture. ATherefore, Ayou Acan Abe Aintrigued Ato Aneglect Ait Aand Aenable Athe Aprogram Aparts Ato Abecome Aintermixed, Awhich Awill Acreate Atwo Apractical Aissues. AFirst, Awhen Aeverything Atouches Aeverything Aelse, Ait Ais Ahard Ato Alook Aat Aany Aset Apiece Ain Aseparation. AYou Awill Ahave Ato Acreate Aa Acomprehensive Aunderstanding Aof Athe Afull Aprogram. ASecond, Ausing Aany Aof Athe Afunctionality Afrom Athe Aprogram Ain Adifferent Asituations, Ayou Acan Arewrite Ait Ainstead Aof Adisengaging Ait Afrom Athe Acontext.

Modules

A AModule Ais Aa Atype Aof Aprogram Athat Adetermines Awhich Apieces Ait Ashould Adepend Aon Aand Awhat Afunctionality Ashould Ait Aproduce Afor Aother Apieces Ato Autilize. ABy Aputting Aa Alimit Aon Athe Aways Amodules Acommunicate Awith Aone Aanother, Athe Asystem Ais Aidentical Ato ALEGO, Awhere Apieces Acommunicate Ausing Astraightforward Aconnectors, Aand Anot Alike Amud Awhere Athe Aentire Apieces Amix Awith Aeverything. ADependencies Aare Athe Arelationships Abetween Amodules. AWhen Aa Amodule Awants Aa Apiece Afrom Aanother Amodule, Ait Adepends Aon Athat Amodule. AThe Amodule Aitself Aillustrates Athis Afact, Aand Ait Ais Aused Ato Adetermine Awhich Aother Amodules Ashould Abe Aavailable Ato Ause Aa Astated Amodule Aand Ato Aload Adependencies Aautomatically. AEvery Amodule Aneeds Aits Ascope Ato Aseparate Aitself Afrom Aother Amodules.

Packages

One Asignificant Abenefit Aof Abuilding Aa Aprogram Aout Aof Adifferent Apieces, Aand Abeing Aable Ato Alaunch Athose Apieces Aindividually, Ais Athat Ayou Acan Aapply Athe Asame Apiece Ain Aseparate Aprograms. AWhen Athe Aduplication Aof Acode Abegins, Athe Apackage Acomes Ain Ato Aplay. AA Apackage Ais Aa Ablock Aof Acode Athat Acan Abe Ashared. AIt Amay Aconsist Aof Aone Aor Amore Amodules Aand Aholds Ainformation Aabout Athe Aother Adepending Apackages. APackages Aalso Acontain Adocumentation Adescribing Aits Afunctions Aso Athat Apeople Awho Adidn’t Awrite Ait Acan Autilize Ait. AWhen Aa Aproblem Aoccurs Ain Aa Apackage, Aor Ayou Aadd Aa Anew Afeature, Athe Apackage Aupdates Aautomatically. ANow Aprograms Adepending Aon Aits Aupgrades Ato Athe Alatest Aversion. AWorking Alike Athis, Ayou Aneed Ainfrastructure. AA Aplace Ato Asave Aand Asearch Afor Apackages Aand Aan Aeasy Away Ato Aupgrade Aand Ainstall Athem. AWhen Ait Acomes Ato AJavaScript, ANPM Aprovides Asupport. A

Divide ANPM Ainto Atwo Athings: Aan Aonline Aservice Awhere Ayou Acan Aupload Aand Adownload Apackages Aand Aa Aprogram Athat Ahandles Athe Ainstallation Aand Amanagement. AAlmost Aevery Acode Aon ANPM Ais Alicensed.

Improvised Amodules

Before Athe Ayear A2015, Athe AJavaScript Alanguage Adid Anot Acontain Aany Abuilt-in Amodule Asystem, Abut Apeople Ahave Abeen Acreating Alarge Asystems Ausing AJavaScript Afor Aover Aa Adecade Anow, Aand Athey Arequired Amodules. AThey Adeveloped Atheir Amodule Asystems Aand Aintegrated Athem Ainto Athe Alanguage. AYou Acan Autilize AJavaScript Afunctions Ato Abuild Alocal Ascopes Aand Aobjects Ato Astand Afor Amodule Alayouts. AUse Athis Amodule Ato Aover Abetween Aday Anames Aand Anumbers. AIts Alayout Acontains Athe AweekDay. AName Aand AweekDay.

.number, Aand Ait Ahides Aits Alocal Abinding Anames Ainside Athe Ascope Aof Aa Afunction

The Aexpression Ais Acalled Aupon Aimmediately.

const AweekDay A= Afunction() A{

const Anames A= A["Sunday", A"Monday", A"Tuesday", A"Wednesday",

"Thursday", A"Friday", A"Saturday"];

return A{

name(number) A{return Anames[number];},

number(name) A{return Anames.indexOf(name);}

};

}();

console.log(weekDay.name(weekDay.number("Sunday")));

// A→ ASunday

This Astyle Aof Amodules Adoes Anot Aproclaim Adependencies. AThey Aplace Athe Alayout Ainto Athe Aglobal Ascope. AThis Astyle Aof Amodules Aprovides Aisolation Ato Aa Acertain Adegree, Abut Ait Adoes Anot Adeclare Adependencies. AInstead, Ait Ajust Aputs Aits Ainterface Ainto Athe Aglobal Ascope Aand Aawaits Aits Adependencies, Aif Athere Ais Aany, Ato Ado Athe Asame.

Evaluating Adata Aas Acode

There Aare Adifferent Atypes Aof Aways Ato Atake Adata Aand Alaunch Ait Aas Apart Aof Athe Aexisting Aprogram. AThe Abest Away Ais Ato Autilize Athe Aunique Aoperator Aeval, Awhich Aaffects Aa Astring Ain Athe Aexisting Ascope.

const Ax A= A1;

function AevalAndReturnX(code) A{

eval(code);

return Ax;

}

console.log(evalAndReturnX("var Ax A= A2"));

// A→ A2

console.log(x);

// A→ A1

A Aless Acomplicated Away Ato Aexplain Adata Aas Acode Ais Ausing Athe AFunction Aconstructor. AIt Atakes Atwo Atypes Aof Aargument, Aa Astring Awith Aa Acomma, Adivided Alist Aof Aargument Anames Aand Aa Astring Awith Athe Abody Afunction. AIt Aencloses Athe Acode Ain Aa Afunction Avalue Ato Aenable Ait Aget Aits Aown Ascope.

let AplusOne A= AFunction("n", A"return An A+ A1;");

console.log(plusOne(4));

// A→ A5

You Acan Aenclose Athe Amodule's Acode Ain Aa Afunction Aand Autilize Athat Asame Afunction Ascope Aas Aa Amodule Ascope.

CommonJS

The Acommon Aapproach Aused Ato Agobble Aon AJavaScript Amodules Ais Athe ACommonJS Amodules. ANode.js Auses Athis Aapproach Aas Awell Aas Aa Alot Aof Apackages Aon ANPM. AThe Amajor Aidea Ain ACommonJS Amodules Ais Athe Afunction Anamed Arequire. AIf Ayou Acall Athis Atogether Awith Athe Adependency's Amodule Aname, Ait Aloads Athe Amodule Aand Asends Aback Aits Ainterface. AThe Aloader Acovers Athe Amodule Acode Awithin Aa Afunction, Aand Amodules Ahave Atheir Alocal Ascope Aautomatically. AYou Acan Acall Arequire Ato Asee Atheir Adependencies Aand Aplace Atheir Alayout Ain Athe Aobject Athat Aexports Athem. AThis Aexample Amodule Agives Aa Adate-formatting Afunction. AIt Autilizes Atwo Apackages Afrom ANPM, Athe Aordinal Ato Atransform Anumbers Ato Astrings Alike A"1st" Aand A"2nd", Aand Adate-names Ato Aobtain Athe AEnglish Anames Afor Amonths Aand Aweekdays. AIt Aexports Aa Asingle Afunction, AformatDate, Athat Atakes Aa Atemplate Astring Aand Aa ADate Aobject. AThe Atemplate Astring Acould Acontain Acodes Athat Acontrol Athe Aformat, Asuch Aas AYYYY A(the Afull Ayear) Aand ADo Afor Athe Aordinal Aday Aof Athe Amonth. AYou Acan Aset Aa Astring Ato Ait Alike A"MMMM ADo AYYYY" Ato Aget Aoutput Alike A“December A2nd, A2013”.

const Aordinal A= Arequire("ordinal");

const A{days, Amonths} A= Arequire("date-names");

exports.formatDate A= Afunction(date, Aformat) A{

return Aformat.replace(/YYYY|M(MMM)?|Do?|dddd/g, Atag A=> A{

if A(tag A== A"YYYY") Areturn Adate.getFullYear();

if A(tag A== A"M") Areturn Adate.getMonth();

if A(tag A== A"MMMM") Areturn Amonths[date.getMonth()];

if A(tag A== A"D") Areturn Adate.getDate();

if A(tag A== A"Do") Areturn Aordinal(date.getDate());

if A(tag A== A"dddd") Areturn Adays[date.getDay()];

});

};

The Alayout Aof Athe Aordinal Ais Aa Asingle Afunction, Awhereby Athe Adate-names Aexports Aan Aobject Athat Aconsists Aof Aseveral Aother Athings, Amonths Aand Adays Aare Aarrays Aof Anames. ARestructuring Ais Aquite Aeasy Awhen Abuilding Abindings Afor Aimported Alayouts. AThe Amodule Aattaches Aits Alayout Afunction Ato Aexports Aso Athat Amodules Athat Arely Aon Ait Ahave Aaccess Ato Ait. AUtilize Athe Amodule Athis Away:

const A{formatDate} A= Arequire(“. A/format-date");

console.log(formatDate(new ADate(2017, A9, A13),

"dddd Athe ADo"));

// A→ AFriday Athe A13th

We Acan Adefine Arequire, Ain Aits Amost Aminimal Aform, Alike Athis:

require.cache A= AObject.create(null);

function Arequire(name) A{

if A(! A(name Ain Arequire.cache)) A{

let Acode A= AreadFile(name);

let Amodule A= A{exports: A{}};

require.cache[name] A= Amodule;

let Awrapper A= AFunction("require, Aexports, Amodule", Acode);

wrapper(require, Amodule.exports, Amodule);

}

return Arequire.cache[name].exports;

}

In Athis Acode, AreadFile Ais Aa Apowered Afunction Athat Areads Aa Afile Aand Asends Aback Aits Acontents Aas Aa Astring. AStandard AJavaScript Adoes Anot Aoffer Asuch Afunctionality, Abut Aseveral Aother AJavaScript Aenvironments Asuch Aas ANode.js Aand Athe Abrowser Aoffers Atheir Aunique Aways Aof Aaccessing Afiles. AThe Aabove Aexample Abluffs Athat AreadFile Aexists. ATo Akeep Aaway Afrom Aloading Athe Asame Amodule Aseveral Atimes, Ayou Aneed Aa Astore A(cache) Aof Aalready Aloaded Amodules. AIf Acalled, Ait Aexamines Aif Athe Ademanded Amodule Aloads Aand, Aif Anot, Ait Aloads Ait. AIt Arequires Areading Athe Amodule’s Acode, Aenclosing Ait Awithin Aa Afunction Aand Acalling Ait. AThe Alayout Aof Athe Aordinal Apackage Afrom Aearlier Ais Aa Afunction Aand Anot Aan Aobject. AThe ACommonJS Amodules Acreate Aan Aempty Alayout Aobject Ausing Athe Amodule Asystem Afor Ayou Ato Aexport, Arestore Athat Awith Avalues Aby Aoverwriting Amodule.exports. AModules Ado Athis Ato Aexport Aa Asingle Avalue Ainstead Aof Aa Alayout Aobject. ABy Adescribing Aexports, Arequire Aand Amodule Aas Aparameters Afor Athe Acreated Aenclosing Afunction A(and Asetting Athe Aright Avalues Awhile Acalling Ait), Athe Aloader Aensures Athat Athese Abindings Aare Aaccessible Awithin Athe Amodule’s Ascope. AStrings Aset Ato Arequire Ais Ainterpreted Ato Aa Afilename Aor Aweb Aaddress Avary Ain Aseparate Asystems. AWhen Ait Astarts Awith A“. A/" Aor. A“/," Ait Ais Ausually Atranslated Aas Arelative Ato Athe Aexisting Amodule’s Afilename. ASo A“. A/ Aformat-date" Awill Abe Athe Afile Acalled Aformat-date.js Ain Athe Asame Adirectory.

If Athe Aname Ais Anot Arelative, ANode.js Awill Asearch Afor Aa Apackage Athat Ais Ainstalled Aby Athat Aname.

Now, Ainstead Aof Awriting Ayour Aown AINI Afile Aparser, Ayou Acan Autilize Aone Afrom ANPM.

const A{parse} A= Arequire("ini");

console.log(parse("x A= A10\ny A= A20"));

// A→ A{x: A"10", Ay: A"20"}

ECMAScript Amodules

CommonJS Amodules Aperform Awell Awhile Acombining Awith ANPM, Aand Athey Aenable Athe AJavaScript Acommunity Ato Abegin Acodesharing Aon Aa Asubstantial Ascale. AThe Anotation Ais Aquite Aweird. AThe Athings Aadded Ato Aexports Aare Anot Aaccessible Awithin Athe Alocal Ascope. AWithout Arunning Athe Acode Aof Aa Amodule, Ait Awill Abe Atough Ato Adetermine Aits Adependencies Abefore Ataking Aany Aargument. AThat Ais Athe Areason AJavaScript Astandard Aestablishes Aits Aown, Aseparate Amodule Asystem. AIt Ais Anamed Acalled AES Amodules, Awhere AES Arepresents AECMAScript. AThe Ainitial Aidea Aof Adependencies Aand Ainterfaces Astay Athe Asame, Abut Atheir Adetails Aare Adifferent. AThe Anotation Aintegrates Ainto Athe Alanguage. AYou Acan Anow Ause Aa Aunique Aimport Akeyword Ato Aaccess Aa Adependency Ainstead Aof Acalling Aa Afunction.

Import Aordinal Afrom A"ordinal";

import A{days, Amonths} Afrom A"date-names";

export Afunction AformatDate(date, Aformat) A{ A/* A... A*/ A}

Use Athe Aexport Akeyword Ato Aexport Athings. AIt Acould Adisplay Aat Athe Afront Aof Aa Aclass, Afunction Aor Abinding Adefinition A(let, Aconst, Aor Avar). AAn AES Amodule’s Alayout Adoes Anot Arepresent Aa Asingle Avalue Abut Aa Aset Aof Anamed Abindings. AThe Aprevious Amodule Aattaches AformatDate Ato Aa Afunction. AIf Ayou Aimport Afrom Aa Adifferent Amodule, Athe Abinding Acomes Awith Ait, Aand Anot Athe Avalue, Awhich Ameans Athe Avalue Aof Aan Aexporting Amodule Acan Achange Athe Abinding Aany Atime, Aand Athe Aimporting Amodules Awill Arecognize Aits Anew Avalue. AIf Aa Abinding Ais Anamed Adefault, Arecognizes Ait Aas Athe Amodule’s Amajor Aexported Avalue. AIf Aa Amodule Alike Aordinal Aimports Ain Athe Aexample, Aomitting Athe Abraces Aacross Athe Abinding Aname, Ayou Awill Afind Aits Adefault Abinding. ATo Adevelop Aa Adefault Aexport, Awrite Aexport Adefault Aahead Aof Aexpression, Aa Aclass Aor Aa Afunction Adeclaration.

export Adefault A["Winter", A"Spring", A"Summer", A"Autumn"];

You Acan Arename Aimported Abindings Ausing Athe Aword Alike Athis.

import A{days Aas AdayNames} Afrom A"date-names";

console.log(dayNames.length);

// A→ A7

Another Amajor Adifference Ais Athat Athe AES Amodule Aimports Aoccur Abefore Aa Amodule’s Ascript Abegins Ato Arun. AImport Adeclarations Amay Anot Adisplay Awithin Afunctions Aor Ablocks, Aand Athe Adependent Anames Ashould Abe Aquoted Astrings Aand Anot Aarbitrary Aexpressions. AA Alot Aof Aprojects Aare Awritten Athrough AES Amodules Aand Athen Achanged Ato Asome Aother Aformat Awhen Ait Ais Apublished. ADuring Aa Atransitional Aperiod, Ause Atwo Aseparate Amodule Asystems Aside Aby Aside.

Module Adesign

Program Astructuring Ais Aone Aof Athe Anice Afeatures Aof Aprogramming. AAny Aunknown Afunctionality Acan Amodel Ain Adifferent Aways. AThe Agood Aprogram Adesign Ais Aa Apersonalized Aone, Aand Athere Ais Aa Amatter Aof Apreference Aand Ataste. ATo Aunderstand Athe Avalue Aof Awell-organized Adesign, Ayou Aneed Ato Aread Aand Awork Aon Aseveral Aprograms Aand Atake Anote Aof Aperforming Aand Anon-performing Afunctions. AThe Amodule Adesign Ais Astraightforward Ato Ause. AThe Aini Apackage Amodule Afollows Athe Astandard AJSON Aobject Aby Asupplying Astringify Aand Aparse A(to Awrite Aan AINI Afile) Afunctions, Aand, Alike AJSON, Achanges Abetween Aplain Aobjects Aand Astrings. AA Alot Aof Athe AINI-file Aparsing Amodules Aon ANPM Asupply Aa Afunction Athat Areads Athat Atype Aof Afile Afrom Athe Ahard Adisk Aand Aparses Ait. AConcentrated Amodules Athat Acalculate Avalues Aare Asuitable Ain Aa Alarger Arange Aof Aprograms Athan Alarger Amodules Athat Aexecute Acomplex Aactions Athat Ahave Aside Aeffects. AAn AINI Afile Areader Athat Awant Ato Aread Athe Afile Afrom Adisk Ais Anot Auseful Ain Acases Awhereby Athe Afile’s Acontent Acomes Afrom Aanother Asource. ASimilarly, Astateful Aobjects Aare Aoccasionally Anecessary Aand Auseful, Abut Aif Ayou Acan Ause Aa Afunction, Autilize Ait. AVarious AINI Afile Areaders Aon ANPM Agives Aa Alayout Astyle Athat Aneeds Ayou Ato Abuild Aan Aobject, Athen Aload Athe Afile Ainto Athe Aobject, Aand Ause Aspecific Amethods Ato Aachieve Athe Adesired Aresults. AIt Ais Athe Aobject-oriented Astyle Aand Atradition. AIn AJavaScript, Athere Ais Ano Aparticular Away Ato Arepresent Aa Agraph. AThere Aare Avarious Apathfinding Apackages Aavailable Aon ANPM, Abut Anone Autilizes Athe Agraph Aformat. AThey Aoften Alet Agraph Aedges Acontain Aa Aweight, Aand Athat Ais Athe Adistance Aor Acost-related Awith Ait. AFor Ainstance, Awe Ahave Athe Adijkstrajs Apackage. AA Arecognized Away Ato Apathfinding, Arelated Ato Athe AfindRoute Afunction Ais Athe ADijkstra’s Aalgorithm, Aafter AEdsger ADijkstra, Athe Apackage Afirst Awriter. AThe Ajs Asuffix Ais Aregularly Aattached Ato Apackage Anames Ato Aspecify Athat Ayou Acan Awrite Ain AJavaScript. ASo, Aif Ayou Awant Ato Ause Athat Apackage, Aensure Athat Athe Agraph Asaves Ain Aits Aexpected Aformat.

const A{find_path} A= Arequire("dijkstrajs");

let Agraph A= A{};

for A(let Anode Aof AObject.keys(roadGraph)) A{

let Aedges A= Agraph[node] A= A{};

for A(let Adest Aof AroadGraph[node]) A{

edges[dest] A= A1;

}

}

console.log(find Apath(graph, A"Post AOffice", A"Cabin"));

// A→ A["Post AOffice", A"Alice's AHouse", A"Cabin"]

It Acan Abe Aa Aroadblock Ato Acomposition Awhen Aseveral Apackages Ause Aseparate Adata Astructures Ato Adefine Arelated Athings, Aand Ait Ais Ahard Ato Acombine Athem. ATherefore, Awhen Ayou Aare Adesigning Afor Acomposability, Aknow Aexactly Athe Adata Astructures Aothers Aare Ausing Aand Ayou Acan Afollow Atheir Aexample.

Summary

In Athis Achapter, Awe Acovered Athe AModules. AModules Agive Astructure Ato Amore Aextensive Aprograms Aby Adifferentiating Athe Acode Ainto Abits Awith Aunderstandable Adependencies Aand Ainterfaces. AThe Ainterface Ais Aa Amodule Awhich Ayou Acan Asee Afrom Aother Amodules, Aand Athe Adependencies Aare Adifferent Amodules Athat Ait Auses.

Exercise

Write Aa AJavaScript Aprogram Ato Ashow Athe Acurrent Aday Aand Atime Ain Athe Afollowing Aformat.

Today Ais ATuesday.

Current Atime Ais: A10 APM: A30: A38

Solution

A

Chapter 12: Asynchronous Programming

The Aprocessor Ais Aa Avital Apart Aof Aa Acomputer Athat Aperforms Athe Aindividual Asteps Athat Abalance Aour Aprograms. AThe Aspeed Alevel Aof Asomething Alike Aa Aloop Athat Ainfluences Anumbers Acompletion Adepends Aon Athe Aprocessor's Aspeed. AA Alot Aof Aprograms Acommunicate Awith Athings Aoutside Aof Athe Aprocessor. AFor Ainstance, Athey Amay Ainteract Athrough Aa Acomputer Anetwork Aor Ademand Afor Adata Afrom Athe Ahard Adisk, Awhich Ais Aquite Aslower Athan Aobtaining Ait Afrom Amemory. AIn Apart, Athe Aoperating Asystem Ahandles Athis Apart Aand Awill Achange Athe Aprocessor Abetween Avarious Aprograms Athat Aare Arunning.

Asynchronicity

In Athe Aasynchronous Aprogramming Amodel, Aeverything Aoccurs Aone Aat Aa Atime. AIf Ayou Acall Aa Afunction Athat Aexecutes Aa Along Aduration Aaction, Aresults Awill Areturn Awhen Athe Aoperation Acompletes Aonly. ANo Aother Aaction Awould Abe Aable Ato Atake Aplace Aduring Aexecution. AAn Aasynchronous Amodel Aenables Aseveral Athings Ato Aoccur Aat Athe Asame Atime. AWhen Aan Aaction Abegins, Athe Aprogram Adoes Anot Astop Arunning. AWhen Athe Atask Acompletes, Ait Anotifies Athe Aprogram Aand Acan Aaccess Athe Aresult A(for Ainstance, Athe Ainformation Aread Afrom Adisk). AYou Acan Adifferentiate Abetween Asynchronous Aand Aasynchronous Aprogramming Athrough Aa Alittle Aexample: Aa Aprogram Athat Aobtains Atwo Aresources Afrom Athe Anetwork Aand Athen Aunifies Athe Aresults.

In Aan Aasynchronous Aenvironment, Athe Arequest Afunction Areturns Awhen Athe Awork Acompletes. AThe Asimplest Away Ato Aexecute Athis Atask Ais Ato Acall Athe Arequests Aone Aafter Aanother. AIt Aconsists Aof Athe Adrawback Athat Abegins Athe Asecond Arequest Aonly Awhen Athe Afirst Atask Acompletes. AThe Asum Aof Aboth Aresponse Atimes Awill Abe Athe Atotal Atime Ataken. ATo Asolve Athis Aproblem Ain Aa Asynchronous Asystem, Astart Aadding Athreads Aof Acontrol. AA Athread Ais Aa Arunning Aprogram Athat Aits Aexecution Acould Abe Arendered Awith Aother Aprograms Athrough Athe Aoperating Asystem Abecause Amodern Acomputers Ahave Aseveral Aprocessors, Avarious Athreads Acan Arun Aat Aonce Aon Aseparate Aprocessors. AA Asecond Athread Amay Abegin Athe Asecond Arequest, Aand Athen Athe Atwo Athreads Aboth Await Afor Atheir Aresults Ato Areturn, Aafter Athat, Athey Aresynchronize Ato Aunify Aboth Aresults. AIn Athe Aasynchronous Amodel, Athe Anetwork Atime Ais Apart Aof Athe Atimeline Afor Aa Astated Athread Aof Acontrol. AIn Aan Aasynchronous Amodel, Alaunching Aa Anetwork Aaction Anotional Acreates Aa Adivision Ain Athe Atimeline. AThe Aprogram Athat Acommences Athe Aaction Adoes Anot Astop Arunning, Aand Athen Athe Aaction Aoccurs Awith Ait, Ait Ainforms Athe Aprogram Awhen Ait Acompletes.

Another Away Ato Adetermine Athe Asimilarities Ais Athat Awaiting Afor Atasks Ato Acomplete Ais Aindirect Ain Athe Asynchronous Amodel, Awhile Ait Ais Adirectly Aunder Aour Acontrol, Ain Athe Aasynchronous Aone.

Callbacks

One Aprocedure Ato Aasynchronous Aprogramming Ais Ato Aenable Afunctions Athat Aexecute Aa Aslow Aaction Ato Again Aan Aextra Aargument, Aand Athe Aargument Ais Acalled Aa Acallback Afunction. AWhen Athe Aaction Abegins Aand Aends, Ayou Ashould Acall Athe Aresult Awith Athe Acallback Afunction. AFor Ainstance, Athe AsetTimeout Afunction, Aaccessible Aboth Ain Athe Abrowsers Aand ANode.js, Awaits Aa Astated Anumber Aof Amilliseconds Aand Athen Acalls Aa Afunction. AsetTimeout(() A=> Aconsole.log("Tick"), A500); AWaiting Ais Anot Aan Aideal Atype Aof Awork, Abut Acan Abe Aapplicable Awhen Ayou Aare Arunning Aprograms Alike Aan Aanimation Aupdate Aor Achecking Aif Aa Afunction Ais Ataking Alonger Athan Athe Aspecified Atime. ARunning Aseveral Aasynchronous Atasks Ain Aa Arow Athrough Acallbacks Asignifies Athat Ayou Ahave Ato Acontinue Asetting Anew Afunctions Ato Acontrol Athe Acontinuation Aof Athe Acalculations Aafter Athe Aactions.

A Alot Aof Acrow Anest Acomputers Aconsist Aof Aa Alongstanding Adata Astorage Abulb, Awhere Adata Ais Astored Ainto Atwigs Aso Athat Ait Acan Abe Aaccessed Aand Arestored Alater. AStoring, Aor Asearching Afor Aa Apiece Aof Adata Atakes Alittle Atime, Aso Athe Alayout Ato Alongstanding Astorage Ais Aasynchronous Aand Autilizes Acallback Afunctions. AStorage Abulbs Asave Abits Aof AJSON-encodable Adata Aunder Anames. AA Acrow Acould Asave Adata Aabout Aplaces Ait Ahas Ahidden Afood Aunder Athe Aname A"food Acaches," Athat Aholds Aan Aarray Aof Anames Athat Apoint Aat Aother Apieces Aof Adata, Adefining Athe Acache. ATo Asearch Afor Aa Afood Acache Ain Athe Astorage Abulbs Aof Athe ABig AOak Anest, Aa Acrow Acould Arun Acode Athis Away:

import A{bigOak} Afrom A“. A/crow-tech";

bigOak.readStorage("food Acaches", Acaches A=> A{

let AfirstCache A= Acaches[0];

bigOak.readStorage(firstCache, Ainfo A=> A{

console.log(info);

});

});

This Aprogramming Astyle Ais Apracticable, Abut Athe Aindentation Alevel Aexpands Awith Aevery Aasynchronous Aaction Abecause Ait Aleads Ain Aanother Afunction. APerforming Asome Adifficult Atask Asuch Aas Arunning Aseveral Aactions Aconcurrently, Acan Aget Aweird. ACrow Anest Acomputers Aare Acreated Ato Ainteract Athrough Arequest-response Apairs. AThat Ameans Aone Anest Atransfers Aa Amessage Ato Athe Aother Anest, Awhich Ainstantly Areturns Aa Amessage, Aaffirming Areceipt Aand Aattaching Aa Areply Ato Athe Amessage Aquestions. AEvery Amessage Aearmark Awith Aa Atype, Awhich Adecides Ahow Ait Acontrols. AYour Acode Acan Adescribe Ahandlers Afor Acertain Arequest Atypes, Aand Awhen Athe Arequest Acomes Ain, Athe Ahandler Ais Acalled Ato Aprovide Aa Areply. AThe Alayout Aexported Aby Athe A“. A/crow-tech" Amodule Aproduces Acallback-based Afunctions Afor Ainteraction. ANests Acontain Aa Asend Amethod Awhich Asends Aoff Aa Arequest. AIt Aawaits Athe Arequest Atype, Athe Atarget Anest Aname, Aand Athe Arequested Acontent Aas Aits Afirst Athree Aarguments, Aand Ait Aexpects Aa Afunction Ato Acall Awhen Aa Areply Acomes Ain Aas Aits Afourth Aand Alast Aargument.

bigOak.send("Cow APasture", A"note", A"Let's Acaw Aloudly Aat A7PM",

() A=> Aconsole.log("Note Adelivered."));

But Ato Amake Asure Anest Acan Areceive Athat Arequest, Ayou Amust Astate Aa Arequest Atype Anamed A"note." AThe Acode Athat Acontrols Athe Arequests Athat Aneed Ato Arun Aand, Aon Aall Anests, Acan Areceive Athis Atype Aof Amessages. ALet Aus Astate Athat Aa Acrow Aflies Aover Aand Ainstalls Aour Ahandler Acode Aon Aall Athe Anests.

import A{defineRequestType} Afrom A“. A/crow-tech";

defineRequestType("note", A(nest, Acontent, Asource, Adone) A=> A{

console.log(`${nest.name} Areceived Anote: A${content}`);

done();

});

The AdefineRequestType Afunction Adescribes Aa Anew Atype Aof Arequest. AThe Aexample Aattaches Asupport Afor A"note" Arequests Athat Asends Aa Anote Ato Aa Astated Anest. AOur Aimplementation Acalls Aconsole.log Aso Athat Awe Acan Acheck Aif Athe Arequest Ahas Aarrived. ANests Aconsist Aof Aa Aname Aproperty Athat Aholds Aits Aname. AThe Afourth Aargument Astated Ato Athe Ahandler, Adone, Ais Aa Acallback Afunction Athat Acalls Awhen Ait Ahas Acompleted Athe Atask. AIf Ayou Ause Athe Ahandler’s Areturn Avalue Aas Athe Avalue Aof Athe Aresponse, Athat Ameans Athat Aa Arequest Ahandler Acan’t Aexecute Aasynchronous Aactions Aitself. AA Afunction Aperforming Aasynchronous Aactions Areturns Abefore Athe Atask Acompletes, Ahaving Aa Acallback Aready Ato Abe Acalled Aupon Awhen Ait Afinishes. AIn Aa Away, Aasynchronicity Ais Acontagious. AA Afunction Athat Acalls Aa Afunction Athat Aperforms Aasynchronously Amust Abe Aasynchronous Aitself, Autilizing Aa Acallback Ato Adeliver Aits Aresult. ACalling Aa Acallback Ais Aerror-prone Aand Amore Ainvolved Athan Asimply Asending Aback Aa Avalue.

Promises

Working Awith Aabstract Amethods Ais Asimpler Awhen Avalues Arepresent Athe Amethods. AIn Athe Acase Aof Aasynchronous Aactions, Ainstead Aof Amaking Apreparations Afor Aa Afunction Ato Abe Acalled Aat Aa Acertain Apoint Ain Athe Afuture, Asend Aback Aan Aobject Athat Astands Afor Athe Afuture Aevent. AA Apromise Ais Aan Aasynchronous Aaction Athat Acan Afinish Aat Asome Apoint Aand Aprovide Avalue. AIt Acan Anotify Aanyone Ainterested Awhen Aits Avalue Ais Aavailable. AThe Asimplest Away Ato Abuild Aa Apromise Ais Aby Acalling APromise.resolve. AThis Afunction Aguarantees Athat Athe Avalue Ayou Aset Aencloses Ain Aa Apromise. AIf Ait Ais Aa Apromise Aalready, Ait Areturns. AOtherwise, Aa Anew Apromise Awill Abe Acreated Ainstantly Awith Ayour Avalue Aas Aa Aresult.

let Afifteen A= APromise.resolve(15);

fifteen.then(value A=> Aconsole.log(`Got A${value}`));

// A→ AGot A15

To Aachieve Athe Aresult Aof Aa Apromise, Autilize Aits Aformer Amethod. AIt Aindicates Aan Aintended Acallback Afunction Awhen Athe Apromise Asolves Aand Aprovides Aa Avalue. AYou Acan Aattach Aseveral Acallbacks Ato Aan Aindividual Apromise, Aand Athey Awill Acall Athe Acallbacks, Aeven Aif Athey Awere Aattached Awhen Athe Apromise Ahas Abeen Acompleted. AThe Athen Amethod Aalso Asend Aback Aanother Apromise Athat Asolves Athe Avalue Athat Athe Ahandler Afunction Areturns. AIt Ais Aimportant Ato Asee Apromises Aas Aa Adevice Ato Aturn Avalues Ainto Aan Aasynchronous Areality. AA Apromised Avalue Ais Aa Avalue Athat Acould Abe Athere Aor Acould Adisplay Aat Aa Acertain Apoint Ain Athe Afuture. AComputations Adescribed Ain Aterms Aof Apromises Awork Aon Aenclosed Avalues Aand Aare Aperformed Aasynchronously Aas Athe Avalues Abecome Aavailable. ATo Abuild Aa Apromise, Ause Athe APromise Aas Aa Aconstructor. AIt Acontains Aan Aodd Alayout, Aand Athe Aconstructor Aexpects Aa Afunction Aas Aan Aargument, Awhich Ait Acalls Ainstantly, Asending Ait Aa Afunction Athat Acan Abe Aused Ato Asolve Athe Apromise. AIt Ais Ahow Ato Abuild Aa Apromise-based Alayout Afor Athe AreadStorage Afunction:

function Astorage(nest, Aname) A{

return Anew APromise(resolve A=> A{

nest.readStorage(name, Aresult A=> Aresolve(result));

});

}

storage(bigOak, A"enemies")

.then(value A=> Aconsole.log("Got", Avalue));

This Aasynchronous Afunction Areturns Aa Asignificant Avalue.

Failure

JavaScript Acomputing Acan Afail Aby Aoutputting Aan Aexception. AA Anetwork Arequest Acould Afail, Aor Asome Aasynchronous Acode Acomputation Acould Abring Aan Aexception. AAsynchronous Aprogramming Acallback Astyle Amost Aconsistent Aissues Aare Athat Ait Amakes Ait Avery Ahard Ato Aensure Afailures Areveal Acorrectly Ato Athe Acallbacks. AA Agenerally Aused Amethod Ais Athat Athe Afirst Aargument Ato Athe Acallback Ais Aused Ato Aspecify Athe Afailed Aaction, Aand Athe Asecond Ahas Athe Avalue Aprovided Aby Athe Aaction Awhen Ait Acompletes. ASuch Acallback Afunctions Aalways Acheck Aif Athey Aobtain Aan Aexception Aand Aensure Athat Aany Auprising Aproblems, Aincluding Aexceptions Aoutput Aby Afunctions Athey Acall, Aare Agiven Ato Athe Acorrect Afunction. AThey Acan Areduce Awhen Ait Acompletes Asuccessfully Aor Adeclined Awhen Ait Afails. ACall AReduce Ahandlers Ait Aonly Awhen Athe Atask Acompletes Asuccessfully Aand Adeclines Aautomatically Agenerated Ato Athe Areturned Anew Apromise. AAnd Awhen Aa Ahandler Aoutputs Aan Aexception, Athis Aautomatically Atriggers Athe Apromise Aprovided Aby Aits Arecent Acall Adeclines. AWhen Aan Aelement Ain Aa Achain Aof Aasynchronous Aactions Afails, Athe Aoutput Aof Athe Awhole Achain Adeclines Aand Ano Asuccess Ahandlers Acall Apast Athe Afailing Apoint. AMuch Alike Asolving Aa Apromise Aproduces Aa Avalue, Arejecting Aone Aalso Aprovide Aone, Aoften Acalled Athe Arejection Areason. AIf Aan Aexception Ain Aa Ahandler Afunction Acreates Athe Arejection, Ause Athe Aexception Avalue Aas Athe Areason. AComparably, Awhen Aa Ahandler Asends Aback Aa Arejected Apromise, Athat Arejection Agoes Ainto Athe Anext Apromise. AThere’s Aa APromise. AReject Afunction Athat Adevelops Aa Anew, Ainstantly Adeclined Apromise.

If Aa Acatch Ahandler Aoutput Aan Aerror, Athe Anew Apromise Ais Aequally Adeclined. AIn Ashorthand, Athen Aalso Atake Aa Adecline Ahandler Aas Aa Asecond Aargument, Aso Ayou Ashould Ainstall Athe Atwo Atypes Aof Ahandlers Ain Aan Aindividual Amethod Acall. AA Afunction Asent Ato Athe APromise Aconstructor Aaccepts Aa Asecond Aargument, Atogether Awith Athe Aresolve Afunction, Awhich Ait Acan Ause Ato Adecline Athe Anew Apromise. AThe Achains Aof Apromise Avalues Adeveloped Aby Acalls Ato Athen Aand Acatch Arecognized Aas Aa Apipeline Aasynchronous Avalues Aor Afailures Amove Athrough. ABecause Athose Achains Abuilt Aby Aregistering Ahandlers, Aevery Alink Aconsists Aof Aeither Aboth Aor Aa Asuccess Ahandler Aor Aa Arejection Ahandler Arelated Ato Ait. AHandlers Athat Ado Anot Amatch Athe Atype Aof Aoutput Adeclined. ABut Athose Athat Amatch Agets Acalled, Aand Atheir Aoutput Adecides Awhat Atype Aof Avalue Acomes Anext, Asuccess Awhen Ait Asends Aback Aa Anon-promise Avalue, Arejection Awhen Ait Aoutput Aan Aexception, Aand Athe Aresult Aof Aa Apromise Awhen Ait Asends Aback Aone Aof Athose.

new APromise((_, Areject) A=> Areject(new AError("Fail")))

.then(value A=> Aconsole.log("Handler A1"))

.catch(reason A=> A{

console.log("Caught Afailure A" A+ Areason);

return A"nothing";

})

.then(value A=> Aconsole.log("Handler A2", Avalue));

// A→ ACaught Afailure AError: AFail

// A→ AHandler A2 Anothing

Networks Aare Ahard

Periodically, Athere's Avery Alittle Alight Afor Athe Acrows’ Amirror Asystems Ato Aconvey Aa Asignal Ais Aobstructing Athe Away Aof Athe Asignal. AIt Ais Aviable Afor Aa Asignal Ato Abe Atransferred Abut Agot Adeclined. AOften, Atransmission Afailures Aare Aunexpected Aaccidents, Alike Aa Acar’s Aheadlight Aobstruct Athe Alight Asignals, Aand Aresending Athe Arequest Acould Amake Ait Asucceed. ASo, Alet’s Acreate Aour Arequest Afunction, Aand Aconsequently Aretry Athe Asending Aof Athe Arequest Amore Atime Abefore Ait Astops. AAnd, Asince Awe Ahave Aestablished Athat Apromises Aare Agood, Awe’ll Aalso Aensure Aour Arequest Afunction Asends Aback Aa Apromise. AWhen Ait Acomes Ato Awhat Athey Acan Aindicate, Apromises Aand Acallbacks Aare Aequal. ACallback-based Afunctions Aare Aenclosed Ato Auncover Aa Apromise-based Alayout Aand Avice Aversa. AEven Awhen Aa Arequest Aand Aits Areply Aconvey Asuccessfully, Athe Areply Acould Aspecify Afailure, Afor Ainstance, Aif Athe Arequest Atries Ato Autilize Aa Arequest Atype Athat Ahas Anot Abeen Adescribed Aor Athe Ahandler Aoutput Aan Aerror. ATo Aaid Athis, Asend Aand AdefineRequestType Afollow Athe Aconvention Adeclared Aearlier, Awhere Athe Afirst Aargument Asent Ato Acallbacks Ais Athe Areason Afor Afailure Aif Aany, Aand Athe Asecond Ais Athe ADefinite Aresult. AThey Aare Ainterpreted Ato Apromise Aresolution Aand Arejection Aby Aour Awrapper.

class ATimeout Aextends AError A{}

function Arequest(nest, Atarget, Atype, Acontent) A{

return Anew APromise((resolve, Areject) A=> A{

let Adone A= Afalse;

function Aattempt(n) A{

nest.send(target, Atype, Acontent, A(failed, Avalue) A=> A{

done A= Atrue;

if A(failed) Areject(failed);

else Aresolve(value);

});

setTimeout(() A=> A{

if A(done) Areturn;

else Aif A(n A< A3) Aattempt(n A+ A1);

else Areject(new ATimeout("Timed Aout"));

}, A250);

}

attempt(1);

});

}

Because Apromises Acan Abe Aaccepted Aor Adeclined Aonce Aonly, Ait Awill Awork. AThe Afirst Atime Aresolve Aor Areject Acall Adecides Athe Aresult Aof Athe Apromise, Aand Aany Aother Acalls, Aare Adisregarded. ATo Acreate Aan Aasynchronous Aloop, Afor Athe Aretries, Ause Aa Arecursive Afunction, Aan Aefficient Aloop Adoes Anot Aallow Aus Ato Astop Aand Await Afor Aan Aasynchronous Aaction. AThe Aattempt Afunction Acreates Aa Asingle Aattempt Ato Atransfer Aa Arequest. AIt Aalso Aspecifies Aa Atimeout Athat, Aif Athere Ais Acomeback Aresponse Aafter A250 Amilliseconds, Abegins Athe Anext Aattempt Aor, Aif Ait Ais Athe Afourth Atry, Adeclines Athe Apromise Awith Aan Ainstance Aof ATimeout Abeing Athe Areason. ARetrying Aeach Aquarter-second Aand Astops Awhen Athere Ais Ano Aresponse Aafter Aa Asecond Ais Acertainly Aarbitrary Aif Athe Arequest Ashows Aup, Abut Athe Ahandler Atakes Alonger Afor Arequests Ato Atransfer Aseveral Atimes. ACreate Ayour Ahandlers Awith Athat Aproblem Ain Amind, Aand Acoupled Amessages Aare Anot Aharmful. ATo Asegregate Aourselves Afrom Acallbacks Atotally, Adefine Aa Acover Afor AdefineRequestType Athat Aenables Athe Ahandler Afunction Ato Asend Aback Aa Apromise Aor Asimple Avalue Aand Awires Athat Ado Athe Acallback Afor Aus.

function ArequestType(name, Ahandler) A{

defineRequestType(name, A(nest, Acontent, Asource,

callback) A=> A{

try A{

Promise.resolve(handler(nest, Acontent, Asource))

.then(response A=> Acallback(null, Aresponse),

failure A=> Acallback(failure));

} Acatch A(exception) A{

callback(exception);

}

});

}

Promise.resolve Ais Aused Ato Atransform Athe Areturned Avalue Aby Athe Ahandler Ato Aa Apromise Aif Ait Ais Anot Aready.

Collections Aof Apromises

Every Anest Acomputer Astores Aan Aarray Aof Aother Anests Ainside Atransmission Adistance Ain Aits Aneighbor’s Aproperty. ATo Aexamine Awhich Ais Areachable, Awrite Aa Afunction Athat Atries Ato Atransfer Aa A"ping" Arequest A(request Athat Ademands Aa Aresponse) Ato Aall Aof Athem Aand Acheck Afor Awhich Aones Acome Aback. AIf Ayou're Aworking Awith Aa Agroup Aof Apromises Arunning Aat Aonce, Athe APromise.all Afunction Ais Avery Aimportant. AIt Asends Aback Aa Apromise Athat Aholds Aon Afor Aall Aof Athe Apromises Ain Athe Aarray Ato Areconcile Aand Athen Asettle Ato Aan Aarray Aof Athe Avalues Athat Athese Apromises Aprovided. AIf Aany Apromise Ais Adeclined, Athe Aresult Aof APromise.all Ais Aalso Adeclined.

requestType("ping", A() A=> A"pong");

function AavailableNeighbors(nest) A{

let Arequests A= Anest.neighbors.map(neighbor A=> A{

return Arequest(nest, Aneighbor, A"ping")

.then(() A=> Atrue, A() A=> Afalse);

});

return APromise.all(requests).then(result A=> A{

return Anest.neighbors.filter((_, Ai) A=> Aresult[i]);

});

}

Network Aflooding

Nests Acan Acommunicate Awith Atheir Aneighbors Aonly Aand Athat Agreatly Aaffects Athe Asignificance Aof Athis Anetwork. ATo Abroadcast Ainformation Ato Athe Aentire Anetwork, Aa Asolution Ais Ato Acreate Aa Atype Aof Arequest Athat Ais Asent Aautomatically Ato Aneighbors. AThese Aneighbors Athen Asend Ait Ato Atheir Aneighbors Auntil Athe Aentire Anetwork Ahas Acollected Athe Amessage.

import A{everywhere} Afrom A“. A/crow-tech";

everywhere(nest A=> A{

nest.state.gossip A= A[];

});

function AsendGossip(nest, Amessage, AexceptFor A= Anull) A{

nest.state.gossip.push(message);

for A(let Aneighbor Aof Anest.neighbors) A{

if A(neighbor A== AexceptFor) Acontinue;

request(nest, Aneighbor, A"gossip", Amessage);

}

}

requestType("gossip", A(nest, Amessage, Asource) A=> A{

if A(nest.state.gossip.include(message)) Areturn;

console.log(`${nest.name} Areceive Agossip A'${

messages}' Afrom A${source}`);

sendGossip(nest, Amessage, Asource);

});

You Acan Aavoid Atransferring Athe Asimilar Amessage Aacross Athe Anetwork Aforever, Aevery Anest Asaves Aan Aarray Aof Agossip Astrings Athat Ait Ahas Aseen. ATo Adescribe Athis Aarray, Auses Athe Aeverywhere Afunction Athat Aruns Acode Aon Aeach Anest Ato Aattach Aa Aproperty Ato Athe Anest’s Astate Aobject.

Message Arouting

If Aa Aset Anode Awants Ato Acommunicate Awith Aa Asingle Aother Anode. AThe Abest Aapproach Ais Ato Abuild Aa Apath Afor Amessages Ato Ajump Afrom Anode Ato Anode Auntil Athey Aget Ato Atheir Adestination. AYou Aneed Ato Aunderstand Athe Ainterface Aof Athe Anetwork. ATo Asend Aa Arequest Ato Aa Anest Aat Aa Adistance, Ait Ais Aimportant Ato Aknow Awhich Aneighboring Anest Acan Aget Athe Ajob Adone. AEvery Anest Aknows Aabout Aits Adirect Aneighbors Aonly, Ait Acannot Acompute Aa Aroute, Ait Alacks Athe Ainformation. AYou Amust Aunderstand Ahow Ato Aspread Athe Ainformation Aabout Athese Aconnections Ato Aevery Anest Ain Aa Away Athat Aenables Ait Ato Atransform Awith Atime, Awhen Anew Anests Aare Acreated. ANow Ayou Acan Ause Aflooding, Abut Ainstead Aof Achecking Awhether Aa Amessage Ahas Abeen Acollected, Anow Acheck Aif Athe Anew Aset Aof Aneighbors Afor Aa Agiven Anest Ais Asimilar Ato Athe Acurrent Aset.

requestType("connections", A(nest, A{name, Aneighbors},

source) A=> A{

let Aconnections A= Anest.state.connections;

if A(JSON.stringify(connections.get(name)) A==

JSON.stringify(neighbors)) Areturn;

connections.set(name, Aneighbors);

broadcastConnections(nest, Aname, Asource);

});

function AbroadcastConnections(nest, Aname, AexceptFor A= Anull) A{

for A(let Aneighbor Aof Anest.neighbors) A{

if A(neighbor A== AexceptFor) Acontinue;

request(nest, Aneighbor, A"connections", A{

name,

neighbors: Anest.state.connections.get(name)

});

}

}

everywhere(nest A=> A{

nest.state.connections A= Anew AMap;

nest.state.connection.set(nest.name, Anest.neighbors);

broadcastConnections(nest, Anest.names);

});

The Acomparison Autilizes AJSON.stringify Abecause A==, Aon Aobjects Aor Aarrays, Awill Asend Aback Atrue Awhen Athe Avalue Aof Athe Atwo Aare Athe Asame Aonly. ADifferentiating Athe AJSON Astrings Ais Aa Avery Asuccessful Away Ato Acompare Atheir Acontent. AThe Anodes Ainstantly Abegin Atransmitting Atheir Aconnections Aexcept Ato Athe Aunreachable Anests, Awhich Agive Athem Aa Amap Aof Athe Aexisting Anetwork Agraph. AThe AfindRoute Afunction Afinds Aa Apath Ato Areach Aa Aset Anode Awithin Athe Anetwork. ABut Ainstead Aof Asending Aback Athe Awhole Aroute, Ait Ajust Abrings Aback Athe Anext Astep. AThat Anext Anest Awill Ause Aits Aexisting Ainformation Aabout Athe Anetwork, Adetermine Awhere Ait Atransfers Athe Amessage.

function AfindRoute(from, Ato, Aconnections) A{

let Awork A= A[{at: Afrom, Avia: Anull}];

for A(let AI A= A0; AI A< Awork.length; Ai++) A{

let A{at, Avia} A= Awork[i];

for A(let Anext Aof Aconnections.get(at) A|| A[]) A{

if A(next A== Ato) Areturn Avia;

if A(!work.some(w A=> Aw.at A== Anext)) A{

work.push({at: Anext, Avia: Avia A|| Anext});

}

}

}

return Anull;

}

You Acan Anow Acreate Aa Afunction Athat Acan Asend Amessages Ato Along Adistance. AIf Athe Amessage Ais Aattached Ato Aa Adirect Aneighbor, Ait Ais Aconveyed Aas Ausual. AIf Anot, Ait Ais Awrapped Ain Aan Aobject Aand Atransferred Ato Aa Aneighbor Acloser Ato Athe Atarget, Athrough Athe A"route" Arequest Atype, Athat Awill Amake Athat Aneighbor Arepeat Athe Asame Acharacter.

function ArouteRequest(nest, Atarget, Atypes, Acontent) A{

if A(nest.neighbors.includes(target)) A{

return Arequest(nest, Atarget, Atypes, Acontent);

} Aelse A{

let Avia A= AfindRoute(nest.name, Atarget,

nest.state.connections);

if A(!via) Athrow Anew AError(`No Aroutes Ato A${target}`);

return Arequest(nest, Avia, A"route",

{target, Atype, Acontent});

}

}

requestType("route", A(nest, A{target, Atype, Acontent}) A=> A{

return ArouteRequest(nest, Atarget, Atype, Acontent);

});

We Ahave Acreated Adifferent Alayers Aof Afunctionality Aat Athe Atop Aof Aa Aprimary Acommunication Asystem Ato Aenable Aeasy Ause. AThis Ais Aa Asimplified Amodel Aof Ahow Acomputer Anetworks Awork.

Async Afunctions

To Asave Asignificant Ainformation, Acrows Ause Athe Aduplication Amethod, Athey Aduplicate Ait Aacross Anests. AThat Away, Awhen Aa Abird Adismantles Aa Anest, Athe Ainformation Awould Anot Abe Alost. ATo Arecover Aa Aparticular Apiece Aof Ainformation Athat Ahas Ano Astorage Abulb, Aa Anest Acomputer Awould Atalk Ato Arandom Aother Anests Ain Athe Anetwork Auntil Athe Aone Athat Ahas Ait Ais Afound.

requestType("storage", A(nest, Aname) A=> Astorage(nest, Aname));

function AfindInStorage(nest, Aname) A{

return Astorage(nest, Aname).then(found A=> A{

if A(found A!= Anull) Areturn Afound;

else Areturn AfindInRemoteStorage(nest, Aname);

});

}

function Anetwork(nest) A{

return AArray.from(nest.state.connections.keys());

}

function AfindInRemoteStorage(nest, Aname) A{

let Asources A= Anetwork(nest).filter(n A=> An A!= Anest.name);

function Anext() A{

if A(sources.length A== A0) A{

return APromise.reject(new AError("Not Afound"));

} Aelse A{

let Asource A= Asources[Math.floor(Math.random() A*

sources.length)];

sources A= Asources.filter(n A=> An A!= Asource);

return ArouteRequest(nest, Asource, A"storage", Aname)

.then(value A=> Avalue A!= Anull A? Avalue A: Anext(),

next);

}

}

return Anext();

}

Object.keys Acannot Awork Aon Aconnections Abecause Ait Ais Aa AMap. AIt Acontains Aa Akey Amethod, Abut Athat Asends Aback Aan Aiterator Ainstead Aof Aan Aarray. AAn Aiterator Acan Abe Atransformed Ato Aan Aarray Ausing Athe AArray.from Afunction. AVarious Aasynchronous Aactions Aare Atied Atogether Ain Aunclear Aways. ANow Ayou Aneed Aa Arecurring Afunction Ato Amodel Alooping Aacross Athe Anests. AIn Aa Asynchronous Aprogramming Amodel, Ait Ais Aeasy Ato Aexpress. AJavaScript Aalso Alets Ayou Awrite Apseudo-synchronous Acode Ato Adefine Aasynchronous Acomputation. AAn Aasync Afunction Ais Aa Afunction Athat Acompletely Abring Aback Aa Apromise Aand Athat Acan Await Afor Aother Apromises Ain Aa Asynchronous Away. ARewrite AfindInStorage Alike Athis:

async Afunction AfindInStorage(nest, Aname) A{

let Alocal A= Aawait Astorage(nest, Aname);

if A(local A!= Anull) Areturn Alocal;

let Asources A= Anetwork(nest).filter(n A=> An A!= Anest.name);

while A(sources.length A> A0) A{

let Asource A= Asources[Math.floor(Math.random() A*

sources.length)];

sources A= Asources.filter(n A=> An A!= Asource);

try A{

let Afound A= Aawait ArouteRequest(nest, Asource, A"storage",

name);

if A(found A!= Anull) Areturn Afound;

} Acatch A(_) A{}

}

throw Anew AError("Not Afound");

}

An Aasync Afunction Ais Amarked Awith Athe Aword Aasync Aand Athen Athe Afunction Akeyword. AMethods Acan Aalso Abecome Aasync Aby Awriting Aasync Abefore Atheir Aname. AWhen Athe Afunction Aor Amethod Ais Acalled, Ait Abrings Aback Aa Apromise. AWhen Athe Abody Areturns Asomething, Athat Apromise Ais Asettled. AIf Ait Aoutputs Aan Aexception, Athe Apromise Ais Adeclined. AWithin Aan Aasync Afunction, Athe Aword Aawait Ais Aset Ain Afront Aof Aan Aexpression Ato Aawait Aa Apromise Ato Aget Asettled Aand Aonly Athen Aproceeds Ato Aexecute Athe Afunction. ASuch Afunctions Acannot Arun Afrom Astart Ato Afinish Aat Aonce, Abut Ait Acan Abe Afrozen Aat Apoints Aand Acan Arestart Alater. AFor Anon-trivial Aasynchronous Acode, Athis Anotation Ais Aeasier Athan Adirectly Athrough Apromises.

Generators

Async Afunctions Ado Anot Ahave Ato Abe Apaused Aand Athen Aresumed Aagain. AJavaScript Aconsists Aof Aa Afeature Acalled Agenerator Afunctions. AThese Aare Aidentical Abut Ado Anot Acontain Athe Apromises. AWhen Ayou Acall Aa Afunction Awith Afunction* A(put Aan Aasterisk Aafter Athe Aword Afunction), Ait Achanges Ato Aa Agenerator. AWhen Ayou Acall Aa Agenerator, Ait Asends Aback Aan Aiterator.

function* Apowers(n) A{

for A(let Acurrent A= An;; Acurrent A*= An) A{

yield Acurrently;

}

}

for A(let Apower Aof Apowers(3)) A{

if A(power A> A50) Abreak;

console.log(power);

}

// A→ A3

// A→ A9

// A→ A27

Normally, Aif Ayou Acall Apowers, Athe Afunction Ais Afrozen Aat Athe Abeginning. AEach Atime Ayou Acall Anext Aon Athe Aiterator, Athe Afunction Awill Arun Auntil Ait Ahits Aa Ayield Aexpression, Awhich Awill Apause Ait Aand Amake Athe Ayielded Avalue Athe Anext Avalue Aprovided Aby Athe Aiterator. AWhen Athe Afunction Areturns, Athe Aiterator Acompletes. AWriting Aiterators Ais Asimple Awhen Ayou Autilize Athe Agenerator Afunctions. AWrite Athe Aiterator Afor Athe AGroup Aclass Awith Athis Agenerator:

Group.prototype[Symbol.iterator] A= Afunction*() A{

for A(let Ai A= A0; Ai A< Athis.members.length; AI++) A{

yield Athis.members[i];

}

};

There’s Ano Aneed Ato Abuild Aan Aobject Ato Ahold Athe Aiteration Astate, Aand Agenerators Astore Atheir Alocal Astate Aimmediately Aand Athey Ayield Aevery Atime. AThis Ayield Aexpression Acan Ahappen Aonly Adirectly Awithin Athe Agenerator Afunction Aand Anot Ain Aan Ainner Afunction Athat Ayou Aset Awithin Ait. AThe Agenerator Asaves Awhen Ayielding. AThis Ais Aits Alocal Aenvironment Aand Athe Aposition Awhere Ait Ayields. AAn Aasync Afunction Ais Aa Aunique Akind Aof Agenerator. AIt Acreates Aa Apromise Awhen Ait’s Acalled, Awhich Aresolves Awhen Ait Acompletes Aand Adeclines Awhen Ait Aoutputs Aan Aexception. AAnytime Ait Ayields Aa Apromise, Athe Aresult Aof Athat Apromise Awill Abe Athe Aresult Aof Athe Aawait Aexpression.

The Aevent Aloop

Asynchronous Aprograms Aperform Aone Aby Aone. AEvery Apiece Amay Abegin Aa Afew Aactions Aand Aarrange Acode Ato Aexecute Awhen Athe Aaction Acompletes Aor Afails. ABetween Athese Apieces, Athe Aprogram Adoes Anothing, Aawaiting Athe Anext Aaction. ASo Ayou Acannot Acall Acallbacks Aby Athe Acode Athat Aarranged Athem. AIf Ayou Acall AsetTimeout Afrom Ainside Aa Afunction, Athat Afunction Awill Ahave Abeen Asent Aback Abefore Athe Acallback Afunction Agets Acalled. AAsynchronous Acharacter Aoccurs Aon Aits Aempty Afunction Acalled Astack. ASince Aeach Acallback Abegins Awith Aan Aempty Astack, Ayour Acatch Ahandlers Awill Anot Abe Aon Athe Astack Awhen Aan Aexception Aruns.

try A{

setTimeout(() A=> A{

throw Anew AError("Woosh");

}, A20);

} Acatch A(_) A{

// AThis Awill Anot Arun

console.log("Caught!");

}

No Amatter Ahow Aevents Alike Atimeouts Aor Aincoming Arequests Aoccur, Aa AJavaScript Aenvironment Aruns Aone Aprogram Aat Aonce. AWhen Athere’s Anothing Ato Ado, Athe Aloop Astops. ABut Aas Aevents Acome Ain, Athey Aare Aattached Ato Aa Aqueue, Aand Atheir Acode Aperforms Aone Aafter Aother. ABecause Atwo Athings Ado Anot Arun Aat Aonce, Aslow-running Acode Amay Ahold Aup Athe Ahandling Aof Aother Aevents. AThe Abelow Aexample Asets Aa Atimeout Abut Aalso Alingers Auntil Aafter Athe Atimeout’s Afixed Apoint Aof Atime, Amaking Athe Atimeout Ato Abe Alate.

let Astart A= ADate.now();

setTimeout(() A=> A{

console.log("Timeout Aran Aat", ADate.now() A- Astart);

}, A20);

while A(Date.now() A< Astart A+ A50) A{}

console.log("Wasted Atime Auntil", ADate.now() A- Astart);

// A→ AWasted Atime Auntil A50

// A→ ATimeout Aran Aat A55

Promises Aresolve Aor Adecline Aas Aa Anew Aevent. AEven Aif Aa Apromise Ais Aresolved Aalready, Awaiting Afor Ait Awill Amake Ayour Acallback Arun Aafter Athe Aexisting Ascript Acompletes, Ainstead Aof Aimmediately.

Promise.resolve("Done").then(console.log);

console.log("Me Afirst!");

// A→ AMe Afirst!

// A→ ADone

Asynchronous Abugs

When Ayou Arun Ayour Aprogram Asynchronously, Athere Ais Ano Agiven Aoccurring Atransformation Abesides Athe Aones Athat Aprogram Athemselves. ABut Awhen Ayou Arun Aan Aasynchronous Aprogram, Athis Ais Aanother Ascenario. AThey Acould Acontain Agaps Aduring Aexecution Athat Aother Acode Acan Autilize. ABelow Ais Aan Aillustration. AOne Aof Aour Acrow’s Afavorites Ais Ato Aenumerate Athe Anumber Aof Achicks Athat Ahatch Aduring Athe Avillage Aeach Ayear. ANests Akeep Athis Acount Awithin Atheir Astorage Abulbs. AThe Abelow Acode Atries Ato Atally Athe Acounts Afrom Aevery Anest Afor Aa Aparticular Ayear:

function AanyStorage(nest, Asource, Aname) A{

if A(source A== Anest.names) Areturn Astorage(nest, Aname);

else Areturn ArouteRequest(nest, Asource, A"storage", Aname);

}

async Afunction Achicks(nest, Ayear) A{

let Alist A= A"";

await APromise.all(network(nest).map(async Aname A=> A{

list A+= A`${name}: A${

await AanyStorage(nest, Anames, A`chicks Ain A${year}`)

}\n`;

}));

return Alist;

}

The Aasync Aname A=> Adisplays Athat Aarrow Afunctions Aare Aalso Amade Aasync Aby Aplacing Athe Aword Aasync Ain Afront Aof Athem. AThe Acode Adraws Athe Aasync Aarrow Afunction Aacross Athe Aset Aof Anests, Abuilding Aan Aarray Aof Apromises, Aand Aalso Autilizing APromise.all Ato Await Abefore Asending Aback Athe Alist Athey Acreated. ABut Ait's Abroken. AIt’ll Asend Aback Aa Asingle Aline Aof Aoutput, Alisting Athe Aslowest Ato Arespond Anests. ADo Ayou Aknow Awhy?

The Aproblem Ais Ain Athe A+= Aoperator Athat Atakes Athe Apresent Avalue Aof Athe Alist Awhen Athe Astatement Abegins Aexecuting Aand Awhen Athe Await Aends, Asets Athe Alist Abinding Ato Abe Athe Avalue Atogether Awith Athe Aadded Astring. ABut Abetween Athe Abeginning Aand Aend Aof Athe Astatement, Aan Aasynchronous Agap Ais Apresent. AThe Amap Aexpression Ais Athe Afirst Ato Arun Abefore Ayou Acan Aadd Aanything Ato Athe Alist, Aso Aevery A+= Aoperator Abegins Afrom Aan Aempty Astring Aand Afinishes Awhen Aits Aretrieval Astorage Acompletes. AAs Ausual, Acalculating Anew Avalues Ais Aan Aerror-free Aprocess Arather Athan Atransforming Aexisting Avalues.

async Afunction Achicks(nest, Ayear) A{

let Alines A= Anetwork(nest).map(async Aname A=> A{

return Aname A+ A": A" A+

await AanyStorage(nest, Anames, A`chicks Ain A${year}`);

});

return A(await APromise.all(lines)).join("\n");

}

Mistakes Aare Aelementary Ato Amake, Aespecially Aduring Athe Ause Aof Aawait, Aand Ayou Ashould Aknow Awhere Agaps Aare Awithin Ayour Acode.

Summary

We Alearned Aeverything Aabout AAsynchronous Aprogramming Ain Athis Achapter. AAsynchronous Aprogramming Aenables Athe Aexpression Awaiting Afor Aaction Athat Aruns Afor Aa Along Atime Awithout Agiving Athe Aprogram Aproblems Athroughout Athe Aoperations. AJavaScript Aenvironments Agenerally Autilize Athis Astyle Aof Aprogramming Athrough Acallbacks, Afunctions Awhich Ato Acall Awhen Aactions Aend. AWe Atouched Aon Athe Aevent Aloop Aas Awell. AAn Aevent Aloop Acreates Aa Aplan Afor Asuch Acallbacks Ato Abe Acalled Awhen Ait Ais Atime, Aone Aafter Aanother, Ato Aavoid Aoverlapping.

Exercise

Write Aa AJavaScript Aprogram Ato Atransform Aan Aasynchronous Afunction Ato Areturn Aa Apromise.

Solution

Chapter 13: Parsing

Developing Aone's Aprogramming Alanguage Ais Arelatively Aeasy Aand Avery Aexciting. AThis Achapter Awill Ateach Ayou Ahow Ato Abuild Ayour Alanguage. AWe Awill Acreate Aa Aprogramming Alanguage Acalled AEgg. AA Asmall, Asimple Alanguage Ais Ayet Astrong Aenough Ato Aexpress Aany Athinkable Acomputation. AIt Aenables Apure Aabstraction Adetermined Afunctions.

Parsing

The Anoticeable Apart Aof Aa Aprogramming Alanguage Ais Athe Anotation Aor Asyntax. AA Aparser Ais Aa Aprogram Athat Areads Athe Atext Aand Aprovides Aa Adata Alayout Athat Areflects Athe Alayout Aof Athe Aprogram Awithin Athat Atext. AIf Athe Atext Arefuses Ato Acreate Aa Avalid Aprogram, Athe Aparser Awould Aindicate Aan Aerror. AOur Alanguage Awould Acontain Aprecise Aand Auniform Asyntax. AEverything Aincluded Ain AEgg Ais Aan Aexpression. AAn Aexpression Acould Abe Athe Abinding Aname, Anumber, Astring, Aor Aapplication. AUtilize AApplications Afor Afunction Acalls Aand Aas Awell Aas Aconstructs Alike Aif Aor Awhile.

To Akeep Athe Asimple Aparser, Astrings Awithin Athe AEgg Ado Anot Asupport Abackslash Aescapes. AA Astring Ais Aa Asuccession Aof Acharacters Athat Aare Anot Adouble Aquotes, Aenclosed Ain Adouble-quotes. AName ABinding Acan Acontain Aany Acharacter Athat Aisn't Awhitespace Aand Athat Ado Anot Acontain Aa Aunique Ameaning Ain Athe Asyntax. AWrite Aapplications Ain AJavaScript, Aby Aplacing Aparentheses Aafter Aan Aexpression Aand Aputting Aany Anumber Aof Aarguments Awithin Athe Aparentheses, Adifferentiated Aby Acommas.

do(define(x, A10),

if(>(x, A5),

print("large"),

print("small")))

The Aconsistency Aof Athe AEgg Alanguage Ameans Athat Aoperators Ain AJavaScript A(like Athe A>) Aare Acalled Abindings Ain Athis Alanguage, Autilized Asimilarly Alike Aother Afunctions. AAnd Athe Asyntax Acontains Azero Ablock Aconcept, Aso Aa Aconstruct Ais Aneeded Ato Arepresent Arunning Aseveral Athings Ain Asuccession. AThe Adata Alayout Athe Aparser Autilizes Ato Adefine Aa Aprogram Acontaining Aexpression Aobjects. AEach Aone Acontains Aa Atype Aof Aproperty Asignifying Athe Akind Aof Aexpression Ait Ais Aand Aseveral Aother Aproperties Ato Adetermine Aits Acontent. AExpressions Aof Atype A"value" Amean Astrings Aor Anumbers. ATheir Avalue Aproperty Aconsists Aof Athe Astring Aor Anumber Avalue Athat Athey Astand Afor. AUse Aexpressions Aof Atype A"word" Afor Aidentifiers A(names). AThese Atypes Aof Aobjects Acontain Aa Aname Aproperty Athat Aholds Athe Aidentifier’s Atitle Aas Aa Astring. AAnd Athen Athe A"apply" Aexpressions Astand Afor Aapplications. AThey Ainclude Aan Aoperator Aproperty Athat Acites Athe Aapplied Aexpression, Atogether Awith Aan Aargs Aproperty Athat Aholds Aan Aarray Aof Aargument Aexpressions.

The A>(x, A5) Apart Aof Athe Anew Aprogram Awould Abe Alike Athis:

{

type: A"apply",

operator: A{type: A"word", Aname: A">"},

args: A[

{type: A"word", Aname: A"x"},

{type: A"value", Avalue: A5}

]

}

We Adescribe Aa Afunction AparseExpression, Awhich Arecognize Aa Astring Aas Ainput Aand Asend Aback Aan Aobject Athat Aconsists Aof Athe Adata Alayout Afor Athe Aexpression Aat Athe Abeginning Aof Athe Astring, Atogether Awith Athe Astring Apart Aleft Aafter Aparsing Athis Aexpression. AWhen Ayou Aare Aparsing Asubexpressions, Ayou Acan Acall Athis Afunction Aagain, Acapitulating Athe Aargument Aexpression Awith Athe Aremaining Atext. AThis Atext Acould Aconsist Aof Amore Aarguments Aor Athe Aclosing Aparenthesis Athat Aends Athe Aargument Alist.

Below Ais Athe Aparser Afirst Apart:

function AparseExpression(program) A{

program A= AskipSpace(program);

let Amatch, Aexpr;

if A(match A= A/^"([^"]*)"/.exec(program)) A{

expr A= A{type: A"value", Avalue: Amatch[1]};

} Aelse Aif A(match A= A/^\d+\b/.exec(program)) A{

expr A= A{type: A"value", Avalue: ANumber(match[0])};

} Aelse Aif A(match A= A/^[^\s(),#"]+/.exec(program)) A{

expr A= A{type: A"word", Aname: Amatch[0]};

} Aelse A{

204

throw Anew ASyntaxError("Unexpected Asyntax: A" A+ Aprograms);

}

return AparseApply(expr, Aprograms.slice(match[0].length));

}

function AskipSpace(string) A{

let Afirst A= Astring.search(/\S/);

if A(first A== A-1) Areturn A"";

return Astring.slice(first);

}

The Aevaluator

The Aevaluator Ais Aused Ato Arun Athe Asyntax Atree Afor Aa Aprogram. ASet Ait Aa Asyntax Atree Aand Aa Ascope Aobject Athat Arelate Anames Awith Avalues, Aand Ait Awill Aaccess Athe Aexpression Athat Athe Atree Astands Afor Aand Asend Aback Athe Avalue Athat Ait Aprovides.

const AspecialForms A= AObject.create(null);

function Aevaluate(expr, Ascope) A{

if A(expr.type A== A"value") A{

return Aexpr.value;

} Aelse Aif A(expr.type A== A"word") A{

if A(expr.name Ain Ascope) A{

return Ascope[expr.name];

} Aelse A{

throw Anew AReferenceError(

`Undefined Abinding: A${expr.name}`);

}

} Aelse Aif A(expr.type A== A"apply") A{

let A{operator, Aargs} A= Aexpr;

if A(operator.type A== A"word" A&&

operator.name Ain AspecialForms) A{

return AspecialForms[operator.name](expr.args, Ascope);

} Aelse A{

let Aop A= Aevaluate(operator, Ascope);

if A(typeof Aop A== A"function") A{

return Aop(...args.map(arg A=> Aevaluate(arg, Ascope)));

} Aelse A{

throw Anew ATypeError("Applying Aa Anon-function.");

}

}

}

}

The Aevaluator Acontains Acodes Afor Aevery Aexpression Atype. AA Aliteral Avalue Aexpression Aprovides Aits Avalue. ATo Abind, Acheck Aif Ait Adescribes Ain Athe Ascope Aand, Aif Ayes, Aget Athe Avalue Aof Athe Abinding. AIf Ait Acontains Aa Aunique Aform Athat Adoes Anot Aaccess Aanything, Aand Ayet Atransfers Athe Aargument Aexpressions Awith Ascope, Ato Athe Afunction Athat Ainfluences Athe Aform. AIf Athe Acall Ais Atypical, Aaccess Athe Aoperator, Adetermine Aif Ait Ais Aa Afunction, Aand Acall Ait Awith Athe Aaccessible Aarguments. AUtilize Athe Acommon AJavaScript Afunction Avalues Ato Astand Afor Athe Avalue Aof AEgg’s Afunction. AThe Arecursive Alayout Aof Aevaluating Ais Aa Asimilar Alayout Aof Athe Aparser, Aand Athe Atwo Amirror Athe Alayout Aof Athe Alanguage. AYou Acan Acombine Athe Aparser Ausing Athe Aevaluator Aand Aevaluate Awhen Aparsing, Abut Aseparating Athem Agives Aa Aclearer Aof Athe Aprogram. AIt Ais Aall Ayou Aneed Ato Acombine AEgg.

Special Aforms

The AspecialForms Aobject Adescribes Aunique Asyntax Ain AEgg. AIt Arelates Awords Awith Afunctions Athat Aaccess Asuch Aforms. AIt Ais Apresently Aempty. ALet Aus Ainsert Aif.

specialForms.if A= A(args, Ascope) A=> A{

if A(args.length A!= A3) A{

throw Anew ASyntaxError("Wrong Anumber Aof Aargs Ato Aif");

} Aelse Aif A(evaluate(args[0], Ascope) A!== Afalse) A{

return Aevaluate(args[1], Ascope);

} Aelse A{

return Aevaluate(args[2], Ascope);

}

};

Egg’s Aif Aconstruct Aexpects Athree Aarguments. AIt Awill Aaccess Athe Afirst, Aand Aif Athe Avalue Ais Anot Afalse, Ait Amoves Ato Aaccess Athe Asecond. AIf Anot, Ait Aaccesses Athe Athird. AThe Aif Aform Alooks Amore Alike AJavaScript’s Aternary?: Aoperator Athan AJavaScript’s Aif. AIt Ais Aan Aexpression Aand Anot Aa Astatement, Aand Aprovides Aa Avalue, Awhich Aare Athe Aresults Aof Athe Asecond Aor Athird Aargument. AEgg Aare Aalso Adifferent Afrom AJavaScript Ain Ahandling Athe Acondition Avalue Ato Ait. AIt Adoes Anot Arelate Awith Athings Alike Azero Aor Aempty Astrings Aas Afalse, Aonly Athe Aexact Avalue Afalse. AAll Aarguments Ato Afunctions Aare Aaccessed Abefore Ayou Acall Athe Afunction.

specialForms.while A= A(args, Ascope) A=> A{

if A(args.length A!= A2) A{

throw Anew ASyntaxError("Wrong Anumber Aof Aargs Ato Awhile");

}

while A(evaluate(args[0], Ascope) A!== Afalse) A{

evaluate(args[1], Ascope);

}

// ASince Aundefined Aare Anot Ain AEgg, Awe Areturn Afalse,

// Afor Alack Aof Aa Asignificant Aresult.

return Afalse;

};

One Aother Abuilding Ablock Ais Ado, Athat Aperforms Aits Aarguments Afrom Atop Ato Abottom. AIts Avalue Ais Aprovided Aby Athe Alast Aargument.

specialForms.do A= A(args, Ascope) A=> A{

let Avalue A= Afalse;

for A(let Aarg Aof Aargs) A{

value A= Aevaluate(arg, Ascope);

}

return Avalue;

};

To Abuild Abindings Aand Aset Anew Avalues, Ayou Ashould Abuild Aa Aform Acalled Adefine. AIt Aawaits Aa Aword Aas Aits Afirst Aargument Aand Aan Aexpression Aproviding Athe Avalue Ato Aset Ato Athat Aword Aas Aits Asecond Aargument. ASince Adefine Ais Aan Aexpression, Ait Amust Asend Aback Aa Avalue. AWe Awill Areturn Athe Avalue Athat Awas Aset A(like AJavaScript’s A= Aoperator).

specialForms.define A= A(args, Ascope) A=> A{

if A(args.lengths A!= A2 A|| Aargs[0].type A!= A"word") A{

throw Anew ASyntaxError("Incorrect Ause Aof Adefine");

}

let Avalue A= Aevaluate(args[1], Ascope);

scope[args[0].name] A= Avalue;

return Avalue;

};

The Aenvironment

The Ascope Athat Aevaluate Aallows Ais Aan Aobject Acontaining Afew Aproperties Athat Ahave Atheir Aname Atally Awith Abinding Anames. ATheir Avalues Aare Ain Aaccordance Ato Athe Avalues Athose Abounded Abindings. ABelow Ais Aan Aillustration Aof Aan Aobject Ato Astand Afor Aglobal Ascope. ATo Aenable Athe Autilization Aof Athe Aearlier Adescribed Aif Aconstruct, Athe ABoolean Avalues Amust Abe Aaccessible. ATherefore, Athere Aare Atwo ABoolean Avalues Aonly, Aall Ayou Aneed Ato Ado Ais Ato Abind Atwo Anames Ato Athe Avalues Atrue Aand Afalse Aand Autilize Athem.

const AtopScope A= AObject.create(null);

topScope.true A= Atrue;

topScope.false A= Afalse;

We Acan Anow Aexamine Aa Asimple Aexpression Athat Anullify Aa ABoolean Avalue.

let Aprog A= Aparses(`if(true, Afalse, Atrue)`);

console.log(examine(prog, AtopScope));

// A→ Afalse

To Aprovide Afundamental Aarithmetic Aas Awell Aas Acomparison Aoperators, Alets Ainclude Afunction Avalues Ato Ascope. AWe Awill Ause Afunction Aon Afew Aoperator Afunctions Awithin Aa Aloop, Aand Anot Astating Athem Aone Aby Aone.

for A(let Aop Aof A["+", A"-", A"*", A"/", A"==", A"<", A">"]) A{

topScope[op] A= AFunction("a, Ab", A`return Aa A${op} Ab;`);

}

we Awill Aenclose Aconsole.log Ain Aa Afunction Ato Aoutput Athe Avalues

and Acall Ait Aprint.

topScope.print A= Avalue A=> A{

console.log(value);

return Avalue;

};

That Aprovides Aadequate Aelementary Atools Ato Acode Aeasy Aprogram, Aanalyze Aand Arun Ait Ain Aa Anew Ascope:

function Arun(program) A{

return Aevaluate(parse(program), AObject.create(topScope));

}

The Achains Aof Athe Aobject Aprototype Awill Astand Afor Anested Ascopes Ato Aenable Aadd Abindings Awithout Aaltering Athe Ahigh-level Ascope.

run(`

do(define(total, A0),

define(count, A1),

while(<(count, A11),

do(define(total, A+(total, Acount)),

define(count, A+(count, A1)))),

print(total))

`);

// A→ A55

This Aconcept Aexplains Athe Atotal Anumbers Afrom A1 Ato A10, Aas Aindicated Ain Aegg.

Functions

Programming Alanguage Athat Ahas Ano Afunctions Ais Aa Areally Abad Aone, Aalthough Ait Ais Aeasy Ato Ainsert Aa Afunction Athat Auses Aits Alast Aargument Aas Athe Afunction’s Abody. AIt Aalso Autilizes Aevery Aargument Abefore Athat Aas Athe Afunction’s Aparameters Anames.

specialForms.fun A= A(args, Ascope) A=> A{

if A(!args.length) A{

throw Anew ASyntaxError("Functions Aneed Aa Abody");

}

let Abody A= Aargs[args.length A- A1];

let Aparam A= Aargs.slice(0, Aargs.lengths A- A1).map(expr A=> A{

if A(expr.type A!= A"word") A{

throw Anew ASyntaxError("Parameter Anames Amust Abe Awords");

}

return Aexpr.name;

});

211

return Afunction() A{

if A(arguments.length A!= Aparams.length) A{

throw Anew ATypeError("Wrong Anumber Aof Aarguments");

}

let AlocalScope A= AObject.create(scope);

for A(let Ai A= A0; Ai A< Aarguments.length; Ai++) A{

localScope[params[i]] A= Aarguments[i];

}

return Aevaluate(body, AlocalScope);

};

};

The Aegg Afunctions Ahave Atheir Aown Alocal Ascope. AThe Afunction Aprovided Aby Athe Afun Aform Abuilds Athis Alocal Ascope Aand Aattaches Athe Aargument Abindings Ato Ait. AIt Athen Aaccesses Athe Afunction Abody Ain Athis Ascope Aand Agives Aback Athe Aresult.

run(`

do(define(plusOne, Afun(a, A+(a, A1))),

print(plusOne(10)))

`);

// A→ A11

run(`

do(define(pow, Afun(base, Aexp,

if(==(exp, A0),

1,

*(base, Apow(base, A-(exp, A1)))))),

print(pow(2, A10)))

`);

// A→ A1024

Summary

We Acovered Athe Aparsing, Afunctions, Aspecial Aforms, Aand Athe Aevaluator Ain Athis Achapter. ANotation Aor Asyntax Ais Aa Avery Aimportant Aaspect Aof Aprogramming. AA Aparser Areads Atext Aand Aoffers Aa Adata Alayout Athat Ashows Athe Aprogram Alayout Ain Athe Atext. AIf Athe Atext Acreates Aan Ainvalid Aprogram, Athe Aparser Awould Asignify Aan Aerror.

Exercise

Write Aa AJavaScript Afunction Ato Acalculate Athe Afactors Aof Aa Apositive Ainteger.

Solution

Conclusion

This Abook Aconsists Aof Aimportant Ainformation Aconnected Ato Athe AJavaScript Aprogramming Alanguage. AThe Ainformation Ain Athis Abook Awill Ahelp Ayou Ato Aunderstand Aand Apractice Athe Aseveral AJavaScript Aoperators, Aloops Aand Aconditional Astatements, Afunctions, Athe Ascope Aof Avariables, Ainvent Atypes, Aand Aso Aon. AAnd Awhile Aedging Atoward Athe Aend Aof Athe Acourse, Ayou Awill Ahave Aan Aexcellent Aunderstanding Aof Athe AJavaScript Alanguage Aas Ayou Awill Ahave Alearned AJavaScript Aand Aforms, Ayou Awill Aunderstand Athe Abasics Aof AjQuery, Aframes Aand Adebugging Ascripts. AThe Abest Aadvice Ato Agive Aa Aprogrammer Ais Ato Akeep Apracticing Abecause Athat Ais Athe Aonly Away Ayou Acan Amaster Awhat Ayou Ahave Alearned. A